mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-30 16:00:55 +00:00
- update glslang to 7.11.3113 (stable release February 8, 2019). This fixes the SPIR-V validation error reported for the shadowmap shader
This commit is contained in:
parent
b5e0451805
commit
06222a1fbf
59 changed files with 12135 additions and 5836 deletions
|
@ -106,6 +106,20 @@ set(HEADERS
|
||||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
# set(BISON_GLSLParser_OUTPUT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp)
|
# set(BISON_GLSLParser_OUTPUT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp)
|
||||||
|
|
||||||
|
# Precompiled header macro. Parameters are source file list and filename for pch cpp file.
|
||||||
|
macro(glslang_pch SRCS PCHCPP)
|
||||||
|
if(MSVC AND CMAKE_GENERATOR MATCHES "^Visual Studio")
|
||||||
|
set(PCH_NAME "$(IntDir)\\pch.pch")
|
||||||
|
# make source files use/depend on PCH_NAME
|
||||||
|
set_source_files_properties(${${SRCS}} PROPERTIES COMPILE_FLAGS "/Yupch.h /FIpch.h /Fp${PCH_NAME} /Zm300" OBJECT_DEPENDS "${PCH_NAME}")
|
||||||
|
# make PCHCPP file compile and generate PCH_NAME
|
||||||
|
set_source_files_properties(${PCHCPP} PROPERTIES COMPILE_FLAGS "/Ycpch.h /Fp${PCH_NAME} /Zm300" OBJECT_OUTPUTS "${PCH_NAME}")
|
||||||
|
list(APPEND ${SRCS} "${PCHCPP}")
|
||||||
|
endif()
|
||||||
|
endmacro(glslang_pch)
|
||||||
|
|
||||||
|
glslang_pch(SOURCES MachineIndependent/pch.cpp)
|
||||||
|
|
||||||
add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS})
|
add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS})
|
||||||
set_property(TARGET glslang PROPERTY FOLDER glslang)
|
set_property(TARGET glslang PROPERTY FOLDER glslang)
|
||||||
set_property(TARGET glslang PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET glslang PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
|
@ -62,6 +62,12 @@ enum TBasicType {
|
||||||
EbtStruct,
|
EbtStruct,
|
||||||
EbtBlock,
|
EbtBlock,
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
EbtAccStructNV,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EbtReference,
|
||||||
|
|
||||||
// HLSL types that live only temporarily.
|
// HLSL types that live only temporarily.
|
||||||
EbtString,
|
EbtString,
|
||||||
|
|
||||||
|
@ -88,6 +94,14 @@ enum TStorageQualifier {
|
||||||
EvqBuffer, // read/write, shared with app
|
EvqBuffer, // read/write, shared with app
|
||||||
EvqShared, // compute shader's read/write 'shared' qualifier
|
EvqShared, // compute shader's read/write 'shared' qualifier
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
EvqPayloadNV,
|
||||||
|
EvqPayloadInNV,
|
||||||
|
EvqHitAttrNV,
|
||||||
|
EvqCallableDataNV,
|
||||||
|
EvqCallableDataInNV,
|
||||||
|
#endif
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
||||||
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
|
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
|
||||||
|
@ -220,6 +234,9 @@ enum TBuiltInVariable {
|
||||||
EbvViewIndex,
|
EbvViewIndex,
|
||||||
EbvDeviceIndex,
|
EbvDeviceIndex,
|
||||||
|
|
||||||
|
EbvFragSizeEXT,
|
||||||
|
EbvFragInvocationCountEXT,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
EbvViewportMaskNV,
|
EbvViewportMaskNV,
|
||||||
EbvSecondaryPositionNV,
|
EbvSecondaryPositionNV,
|
||||||
|
@ -227,6 +244,33 @@ enum TBuiltInVariable {
|
||||||
EbvPositionPerViewNV,
|
EbvPositionPerViewNV,
|
||||||
EbvViewportMaskPerViewNV,
|
EbvViewportMaskPerViewNV,
|
||||||
EbvFragFullyCoveredNV,
|
EbvFragFullyCoveredNV,
|
||||||
|
EbvFragmentSizeNV,
|
||||||
|
EbvInvocationsPerPixelNV,
|
||||||
|
// raytracing
|
||||||
|
EbvLaunchIdNV,
|
||||||
|
EbvLaunchSizeNV,
|
||||||
|
EbvInstanceCustomIndexNV,
|
||||||
|
EbvWorldRayOriginNV,
|
||||||
|
EbvWorldRayDirectionNV,
|
||||||
|
EbvObjectRayOriginNV,
|
||||||
|
EbvObjectRayDirectionNV,
|
||||||
|
EbvRayTminNV,
|
||||||
|
EbvRayTmaxNV,
|
||||||
|
EbvHitTNV,
|
||||||
|
EbvHitKindNV,
|
||||||
|
EbvObjectToWorldNV,
|
||||||
|
EbvWorldToObjectNV,
|
||||||
|
EbvIncomingRayFlagsNV,
|
||||||
|
EbvBaryCoordNV,
|
||||||
|
EbvBaryCoordNoPerspNV,
|
||||||
|
EbvTaskCountNV,
|
||||||
|
EbvPrimitiveCountNV,
|
||||||
|
EbvPrimitiveIndicesNV,
|
||||||
|
EbvClipDistancePerViewNV,
|
||||||
|
EbvCullDistancePerViewNV,
|
||||||
|
EbvLayerPerViewNV,
|
||||||
|
EbvMeshViewCountNV,
|
||||||
|
EbvMeshViewIndicesNV,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// HLSL built-ins that live only temporarily, until they get remapped
|
// HLSL built-ins that live only temporarily, until they get remapped
|
||||||
|
@ -273,6 +317,13 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||||
case EvqPointCoord: return "gl_PointCoord"; break;
|
case EvqPointCoord: return "gl_PointCoord"; break;
|
||||||
case EvqFragColor: return "fragColor"; break;
|
case EvqFragColor: return "fragColor"; break;
|
||||||
case EvqFragDepth: return "gl_FragDepth"; break;
|
case EvqFragDepth: return "gl_FragDepth"; break;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EvqPayloadNV: return "rayPayloadNV"; break;
|
||||||
|
case EvqPayloadInNV: return "rayPayloadInNV"; break;
|
||||||
|
case EvqHitAttrNV: return "hitAttributeNV"; break;
|
||||||
|
case EvqCallableDataNV: return "callableDataNV"; break;
|
||||||
|
case EvqCallableDataInNV: return "callableDataInNV"; break;
|
||||||
|
#endif
|
||||||
default: return "unknown qualifier";
|
default: return "unknown qualifier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,6 +409,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvViewIndex: return "ViewIndex";
|
case EbvViewIndex: return "ViewIndex";
|
||||||
case EbvDeviceIndex: return "DeviceIndex";
|
case EbvDeviceIndex: return "DeviceIndex";
|
||||||
|
|
||||||
|
case EbvFragSizeEXT: return "FragSizeEXT";
|
||||||
|
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case EbvViewportMaskNV: return "ViewportMaskNV";
|
case EbvViewportMaskNV: return "ViewportMaskNV";
|
||||||
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
|
@ -365,6 +419,33 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvPositionPerViewNV: return "PositionPerViewNV";
|
case EbvPositionPerViewNV: return "PositionPerViewNV";
|
||||||
case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
||||||
|
case EbvFragmentSizeNV: return "FragmentSizeNV";
|
||||||
|
case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV";
|
||||||
|
case EbvLaunchIdNV: return "LaunchIdNV";
|
||||||
|
case EbvLaunchSizeNV: return "LaunchSizeNV";
|
||||||
|
case EbvInstanceCustomIndexNV: return "InstanceCustomIndexNV";
|
||||||
|
case EbvWorldRayOriginNV: return "WorldRayOriginNV";
|
||||||
|
case EbvWorldRayDirectionNV: return "WorldRayDirectionNV";
|
||||||
|
case EbvObjectRayOriginNV: return "ObjectRayOriginNV";
|
||||||
|
case EbvObjectRayDirectionNV: return "ObjectRayDirectionNV";
|
||||||
|
case EbvRayTminNV: return "ObjectRayTminNV";
|
||||||
|
case EbvRayTmaxNV: return "ObjectRayTmaxNV";
|
||||||
|
case EbvHitTNV: return "HitTNV";
|
||||||
|
case EbvHitKindNV: return "HitKindNV";
|
||||||
|
case EbvIncomingRayFlagsNV: return "IncomingRayFlagsNV";
|
||||||
|
case EbvObjectToWorldNV: return "ObjectToWorldNV";
|
||||||
|
case EbvWorldToObjectNV: return "WorldToObjectNV";
|
||||||
|
|
||||||
|
case EbvBaryCoordNV: return "BaryCoordNV";
|
||||||
|
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
|
case EbvTaskCountNV: return "TaskCountNV";
|
||||||
|
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
|
case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||||
|
case EbvClipDistancePerViewNV: return "ClipDistancePerViewNV";
|
||||||
|
case EbvCullDistancePerViewNV: return "CullDistancePerViewNV";
|
||||||
|
case EbvLayerPerViewNV: return "LayerPerViewNV";
|
||||||
|
case EbvMeshViewCountNV: return "MeshViewCountNV";
|
||||||
|
case EbvMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||||
#endif
|
#endif
|
||||||
default: return "unknown built-in variable";
|
default: return "unknown built-in variable";
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,16 +229,29 @@ inline const TString String(const int i, const int /*base*/ = 10)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct TSourceLoc {
|
struct TSourceLoc {
|
||||||
void init() { name = nullptr; string = 0; line = 0; column = 0; }
|
void init()
|
||||||
|
{
|
||||||
|
name = nullptr; string = 0; line = 0; column = 0;
|
||||||
|
}
|
||||||
void init(int stringNum) { init(); string = stringNum; }
|
void init(int stringNum) { init(); string = stringNum; }
|
||||||
// Returns the name if it exists. Otherwise, returns the string number.
|
// Returns the name if it exists. Otherwise, returns the string number.
|
||||||
std::string getStringNameOrNum(bool quoteStringName = true) const
|
std::string getStringNameOrNum(bool quoteStringName = true) const
|
||||||
{
|
{
|
||||||
if (name != nullptr)
|
if (name != nullptr) {
|
||||||
return quoteStringName ? ("\"" + std::string(name) + "\"") : name;
|
TString qstr = quoteStringName ? ("\"" + *name + "\"") : *name;
|
||||||
|
std::string ret_str(qstr.c_str());
|
||||||
|
return ret_str;
|
||||||
|
}
|
||||||
return std::to_string((long long)string);
|
return std::to_string((long long)string);
|
||||||
}
|
}
|
||||||
const char* name; // descriptive name for this string
|
const char* getFilename() const
|
||||||
|
{
|
||||||
|
if (name == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
return name->c_str();
|
||||||
|
}
|
||||||
|
const char* getFilenameStr() const { return name == nullptr ? "" : name->c_str(); }
|
||||||
|
TString* name; // descriptive name for this string, when a textual name is available, otherwise nullptr
|
||||||
int string;
|
int string;
|
||||||
int line;
|
int line;
|
||||||
int column;
|
int column;
|
||||||
|
|
|
@ -133,6 +133,15 @@ struct TBuiltInResource {
|
||||||
int maxCullDistances;
|
int maxCullDistances;
|
||||||
int maxCombinedClipAndCullDistances;
|
int maxCombinedClipAndCullDistances;
|
||||||
int maxSamples;
|
int maxSamples;
|
||||||
|
int maxMeshOutputVerticesNV;
|
||||||
|
int maxMeshOutputPrimitivesNV;
|
||||||
|
int maxMeshWorkGroupSizeX_NV;
|
||||||
|
int maxMeshWorkGroupSizeY_NV;
|
||||||
|
int maxMeshWorkGroupSizeZ_NV;
|
||||||
|
int maxTaskWorkGroupSizeX_NV;
|
||||||
|
int maxTaskWorkGroupSizeY_NV;
|
||||||
|
int maxTaskWorkGroupSizeZ_NV;
|
||||||
|
int maxMeshViewCountNV;
|
||||||
|
|
||||||
TLimits limits;
|
TLimits limits;
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
|
||||||
bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler
|
bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler
|
||||||
bool sampler : 1; // true means a pure sampler, other fields should be clear()
|
bool sampler : 1; // true means a pure sampler, other fields should be clear()
|
||||||
bool external : 1; // GL_OES_EGL_image_external
|
bool external : 1; // GL_OES_EGL_image_external
|
||||||
|
bool yuv : 1; // GL_EXT_YUV_target
|
||||||
unsigned int vectorSize : 3; // vector return type size.
|
unsigned int vectorSize : 3; // vector return type size.
|
||||||
|
|
||||||
// Some languages support structures as sample results. Storing the whole structure in the
|
// Some languages support structures as sample results. Storing the whole structure in the
|
||||||
|
@ -116,6 +117,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
|
||||||
combined = false;
|
combined = false;
|
||||||
sampler = false;
|
sampler = false;
|
||||||
external = false;
|
external = false;
|
||||||
|
yuv = false;
|
||||||
structReturnIndex = noReturnStruct;
|
structReturnIndex = noReturnStruct;
|
||||||
|
|
||||||
// by default, returns a single vec4;
|
// by default, returns a single vec4;
|
||||||
|
@ -186,6 +188,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
|
||||||
combined == right.combined &&
|
combined == right.combined &&
|
||||||
sampler == right.sampler &&
|
sampler == right.sampler &&
|
||||||
external == right.external &&
|
external == right.external &&
|
||||||
|
yuv == right.yuv &&
|
||||||
vectorSize == right.vectorSize &&
|
vectorSize == right.vectorSize &&
|
||||||
structReturnIndex == right.structReturnIndex;
|
structReturnIndex == right.structReturnIndex;
|
||||||
}
|
}
|
||||||
|
@ -233,6 +236,9 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
|
||||||
s.append("ExternalOES");
|
s.append("ExternalOES");
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
if (yuv) {
|
||||||
|
return "__" + s + "External2DY2YEXT";
|
||||||
|
}
|
||||||
switch (dim) {
|
switch (dim) {
|
||||||
case Esd1D: s.append("1D"); break;
|
case Esd1D: s.append("1D"); break;
|
||||||
case Esd2D: s.append("2D"); break;
|
case Esd2D: s.append("2D"); break;
|
||||||
|
@ -277,6 +283,7 @@ enum TLayoutPacking {
|
||||||
ElpStd140,
|
ElpStd140,
|
||||||
ElpStd430,
|
ElpStd430,
|
||||||
ElpPacked,
|
ElpPacked,
|
||||||
|
ElpScalar,
|
||||||
ElpCount // If expanding, see bitfield width below
|
ElpCount // If expanding, see bitfield width below
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -456,12 +463,23 @@ public:
|
||||||
nopersp = false;
|
nopersp = false;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
explicitInterp = false;
|
explicitInterp = false;
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
pervertexNV = false;
|
||||||
|
perPrimitiveNV = false;
|
||||||
|
perViewNV = false;
|
||||||
|
perTaskNV = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearMemory()
|
void clearMemory()
|
||||||
{
|
{
|
||||||
coherent = false;
|
coherent = false;
|
||||||
|
devicecoherent = false;
|
||||||
|
queuefamilycoherent = false;
|
||||||
|
workgroupcoherent = false;
|
||||||
|
subgroupcoherent = false;
|
||||||
|
nonprivate = false;
|
||||||
volatil = false;
|
volatil = false;
|
||||||
restrict = false;
|
restrict = false;
|
||||||
readonly = false;
|
readonly = false;
|
||||||
|
@ -495,10 +513,21 @@ public:
|
||||||
bool nopersp : 1;
|
bool nopersp : 1;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
bool explicitInterp : 1;
|
bool explicitInterp : 1;
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
bool pervertexNV : 1;
|
||||||
|
bool perPrimitiveNV : 1;
|
||||||
|
bool perViewNV : 1;
|
||||||
|
bool perTaskNV : 1;
|
||||||
#endif
|
#endif
|
||||||
bool patch : 1;
|
bool patch : 1;
|
||||||
bool sample : 1;
|
bool sample : 1;
|
||||||
bool coherent : 1;
|
bool coherent : 1;
|
||||||
|
bool devicecoherent : 1;
|
||||||
|
bool queuefamilycoherent : 1;
|
||||||
|
bool workgroupcoherent : 1;
|
||||||
|
bool subgroupcoherent : 1;
|
||||||
|
bool nonprivate : 1;
|
||||||
bool volatil : 1;
|
bool volatil : 1;
|
||||||
bool restrict : 1;
|
bool restrict : 1;
|
||||||
bool readonly : 1;
|
bool readonly : 1;
|
||||||
|
@ -508,8 +537,18 @@ public:
|
||||||
|
|
||||||
bool isMemory() const
|
bool isMemory() const
|
||||||
{
|
{
|
||||||
return coherent || volatil || restrict || readonly || writeonly;
|
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
|
||||||
}
|
}
|
||||||
|
bool isMemoryQualifierImageAndSSBOOnly() const
|
||||||
|
{
|
||||||
|
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly;
|
||||||
|
}
|
||||||
|
bool bufferReferenceNeedsVulkanMemoryModel() const
|
||||||
|
{
|
||||||
|
// include qualifiers that map to load/store availability/visibility/nonprivate memory access operands
|
||||||
|
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || nonprivate;
|
||||||
|
}
|
||||||
|
|
||||||
bool isInterpolation() const
|
bool isInterpolation() const
|
||||||
{
|
{
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
@ -518,15 +557,21 @@ public:
|
||||||
return flat || smooth || nopersp;
|
return flat || smooth || nopersp;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
bool isExplicitInterpolation() const
|
bool isExplicitInterpolation() const
|
||||||
{
|
{
|
||||||
return explicitInterp;
|
return explicitInterp;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool isAuxiliary() const
|
bool isAuxiliary() const
|
||||||
{
|
{
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
return centroid || patch || sample || pervertexNV;
|
||||||
|
#else
|
||||||
return centroid || patch || sample;
|
return centroid || patch || sample;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPipeInput() const
|
bool isPipeInput() const
|
||||||
|
@ -593,6 +638,33 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isPerPrimitive() const
|
||||||
|
{
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
return perPrimitiveNV;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPerView() const
|
||||||
|
{
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
return perViewNV;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTaskMemory() const
|
||||||
|
{
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
return perTaskNV;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool isIo() const
|
bool isIo() const
|
||||||
{
|
{
|
||||||
switch (storage) {
|
switch (storage) {
|
||||||
|
@ -616,6 +688,22 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// non-built-in symbols that might link between compilation units
|
||||||
|
bool isLinkable() const
|
||||||
|
{
|
||||||
|
switch (storage) {
|
||||||
|
case EvqGlobal:
|
||||||
|
case EvqVaryingIn:
|
||||||
|
case EvqVaryingOut:
|
||||||
|
case EvqUniform:
|
||||||
|
case EvqBuffer:
|
||||||
|
case EvqShared:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// True if this type of IO is supposed to be arrayed with extra level for per-vertex data
|
// True if this type of IO is supposed to be arrayed with extra level for per-vertex data
|
||||||
bool isArrayedIo(EShLanguage language) const
|
bool isArrayedIo(EShLanguage language) const
|
||||||
{
|
{
|
||||||
|
@ -626,6 +714,13 @@ public:
|
||||||
return ! patch && (isPipeInput() || isPipeOutput());
|
return ! patch && (isPipeInput() || isPipeOutput());
|
||||||
case EShLangTessEvaluation:
|
case EShLangTessEvaluation:
|
||||||
return ! patch && isPipeInput();
|
return ! patch && isPipeInput();
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EShLangFragment:
|
||||||
|
return pervertexNV && isPipeInput();
|
||||||
|
case EShLangMeshNV:
|
||||||
|
return ! perTaskNV && isPipeOutput();
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -637,13 +732,17 @@ public:
|
||||||
clearUniformLayout();
|
clearUniformLayout();
|
||||||
|
|
||||||
layoutPushConstant = false;
|
layoutPushConstant = false;
|
||||||
|
layoutBufferReference = false;
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
layoutPassthrough = false;
|
layoutPassthrough = false;
|
||||||
layoutViewportRelative = false;
|
layoutViewportRelative = false;
|
||||||
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
||||||
layoutSecondaryViewportRelativeOffset = -2048;
|
layoutSecondaryViewportRelativeOffset = -2048;
|
||||||
|
layoutShaderRecordNV = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
|
||||||
|
|
||||||
clearInterstageLayout();
|
clearInterstageLayout();
|
||||||
|
|
||||||
layoutSpecConstantId = layoutSpecConstantIdEnd;
|
layoutSpecConstantId = layoutSpecConstantIdEnd;
|
||||||
|
@ -675,7 +774,11 @@ public:
|
||||||
hasAnyLocation() ||
|
hasAnyLocation() ||
|
||||||
hasStream() ||
|
hasStream() ||
|
||||||
hasFormat() ||
|
hasFormat() ||
|
||||||
layoutPushConstant;
|
#ifdef NV_EXTENSIONS
|
||||||
|
layoutShaderRecordNV ||
|
||||||
|
#endif
|
||||||
|
layoutPushConstant ||
|
||||||
|
layoutBufferReference;
|
||||||
}
|
}
|
||||||
bool hasLayout() const
|
bool hasLayout() const
|
||||||
{
|
{
|
||||||
|
@ -687,47 +790,53 @@ public:
|
||||||
int layoutOffset;
|
int layoutOffset;
|
||||||
int layoutAlign;
|
int layoutAlign;
|
||||||
|
|
||||||
unsigned int layoutLocation :12;
|
unsigned int layoutLocation : 12;
|
||||||
static const unsigned int layoutLocationEnd = 0xFFF;
|
static const unsigned int layoutLocationEnd = 0xFFF;
|
||||||
|
|
||||||
unsigned int layoutComponent : 3;
|
unsigned int layoutComponent : 3;
|
||||||
static const unsigned int layoutComponentEnd = 4;
|
static const unsigned int layoutComponentEnd = 4;
|
||||||
|
|
||||||
unsigned int layoutSet : 7;
|
unsigned int layoutSet : 7;
|
||||||
static const unsigned int layoutSetEnd = 0x3F;
|
static const unsigned int layoutSetEnd = 0x3F;
|
||||||
|
|
||||||
unsigned int layoutBinding : 16;
|
unsigned int layoutBinding : 16;
|
||||||
static const unsigned int layoutBindingEnd = 0xFFFF;
|
static const unsigned int layoutBindingEnd = 0xFFFF;
|
||||||
|
|
||||||
unsigned int layoutIndex : 8;
|
unsigned int layoutIndex : 8;
|
||||||
static const unsigned int layoutIndexEnd = 0xFF;
|
static const unsigned int layoutIndexEnd = 0xFF;
|
||||||
|
|
||||||
unsigned int layoutStream : 8;
|
unsigned int layoutStream : 8;
|
||||||
static const unsigned int layoutStreamEnd = 0xFF;
|
static const unsigned int layoutStreamEnd = 0xFF;
|
||||||
|
|
||||||
unsigned int layoutXfbBuffer : 4;
|
unsigned int layoutXfbBuffer : 4;
|
||||||
static const unsigned int layoutXfbBufferEnd = 0xF;
|
static const unsigned int layoutXfbBufferEnd = 0xF;
|
||||||
|
|
||||||
unsigned int layoutXfbStride : 10;
|
unsigned int layoutXfbStride : 14;
|
||||||
static const unsigned int layoutXfbStrideEnd = 0x3FF;
|
static const unsigned int layoutXfbStrideEnd = 0x3FFF;
|
||||||
|
|
||||||
unsigned int layoutXfbOffset : 10;
|
unsigned int layoutXfbOffset : 13;
|
||||||
static const unsigned int layoutXfbOffsetEnd = 0x3FF;
|
static const unsigned int layoutXfbOffsetEnd = 0x1FFF;
|
||||||
|
|
||||||
unsigned int layoutAttachment : 8; // for input_attachment_index
|
unsigned int layoutAttachment : 8; // for input_attachment_index
|
||||||
static const unsigned int layoutAttachmentEnd = 0XFF;
|
static const unsigned int layoutAttachmentEnd = 0XFF;
|
||||||
|
|
||||||
unsigned int layoutSpecConstantId : 11;
|
unsigned int layoutSpecConstantId : 11;
|
||||||
static const unsigned int layoutSpecConstantIdEnd = 0x7FF;
|
static const unsigned int layoutSpecConstantIdEnd = 0x7FF;
|
||||||
|
|
||||||
TLayoutFormat layoutFormat : 8;
|
// stored as log2 of the actual alignment value
|
||||||
|
unsigned int layoutBufferReferenceAlign : 6;
|
||||||
|
static const unsigned int layoutBufferReferenceAlignEnd = 0x3F;
|
||||||
|
|
||||||
|
TLayoutFormat layoutFormat : 8;
|
||||||
|
|
||||||
bool layoutPushConstant;
|
bool layoutPushConstant;
|
||||||
|
bool layoutBufferReference;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
bool layoutPassthrough;
|
bool layoutPassthrough;
|
||||||
bool layoutViewportRelative;
|
bool layoutViewportRelative;
|
||||||
int layoutSecondaryViewportRelativeOffset;
|
int layoutSecondaryViewportRelativeOffset;
|
||||||
|
bool layoutShaderRecordNV;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool hasUniformLayout() const
|
bool hasUniformLayout() const
|
||||||
|
@ -829,6 +938,10 @@ public:
|
||||||
// is just whether or not it was declared with an ID.
|
// is just whether or not it was declared with an ID.
|
||||||
return layoutSpecConstantId != layoutSpecConstantIdEnd;
|
return layoutSpecConstantId != layoutSpecConstantIdEnd;
|
||||||
}
|
}
|
||||||
|
bool hasBufferReferenceAlign() const
|
||||||
|
{
|
||||||
|
return layoutBufferReferenceAlign != layoutBufferReferenceAlignEnd;
|
||||||
|
}
|
||||||
bool isSpecConstant() const
|
bool isSpecConstant() const
|
||||||
{
|
{
|
||||||
// True if type is a specialization constant, whether or not it
|
// True if type is a specialization constant, whether or not it
|
||||||
|
@ -863,6 +976,7 @@ public:
|
||||||
case ElpShared: return "shared";
|
case ElpShared: return "shared";
|
||||||
case ElpStd140: return "std140";
|
case ElpStd140: return "std140";
|
||||||
case ElpStd430: return "std430";
|
case ElpStd430: return "std430";
|
||||||
|
case ElpScalar: return "scalar";
|
||||||
default: return "none";
|
default: return "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1005,7 +1119,7 @@ struct TShaderQualifiers {
|
||||||
bool pixelCenterInteger; // fragment shader
|
bool pixelCenterInteger; // fragment shader
|
||||||
bool originUpperLeft; // fragment shader
|
bool originUpperLeft; // fragment shader
|
||||||
int invocations;
|
int invocations;
|
||||||
int vertices; // both for tessellation "vertices" and geometry "max_vertices"
|
int vertices; // for tessellation "vertices", geometry & mesh "max_vertices"
|
||||||
TVertexSpacing spacing;
|
TVertexSpacing spacing;
|
||||||
TVertexOrder order;
|
TVertexOrder order;
|
||||||
bool pointMode;
|
bool pointMode;
|
||||||
|
@ -1018,7 +1132,10 @@ struct TShaderQualifiers {
|
||||||
int numViews; // multiview extenstions
|
int numViews; // multiview extenstions
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
bool layoutOverrideCoverage; // true if layout override_coverage set
|
bool layoutOverrideCoverage; // true if layout override_coverage set
|
||||||
|
bool layoutDerivativeGroupQuads; // true if layout derivative_group_quadsNV set
|
||||||
|
bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set
|
||||||
|
int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
|
@ -1043,7 +1160,10 @@ struct TShaderQualifiers {
|
||||||
blendEquation = false;
|
blendEquation = false;
|
||||||
numViews = TQualifier::layoutNotSet;
|
numViews = TQualifier::layoutNotSet;
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
layoutOverrideCoverage = false;
|
layoutOverrideCoverage = false;
|
||||||
|
layoutDerivativeGroupQuads = false;
|
||||||
|
layoutDerivativeGroupLinear = false;
|
||||||
|
primitives = TQualifier::layoutNotSet;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,6 +1208,12 @@ struct TShaderQualifiers {
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (src.layoutOverrideCoverage)
|
if (src.layoutOverrideCoverage)
|
||||||
layoutOverrideCoverage = src.layoutOverrideCoverage;
|
layoutOverrideCoverage = src.layoutOverrideCoverage;
|
||||||
|
if (src.layoutDerivativeGroupQuads)
|
||||||
|
layoutDerivativeGroupQuads = src.layoutDerivativeGroupQuads;
|
||||||
|
if (src.layoutDerivativeGroupLinear)
|
||||||
|
layoutDerivativeGroupLinear = src.layoutDerivativeGroupLinear;
|
||||||
|
if (src.primitives != TQualifier::layoutNotSet)
|
||||||
|
primitives = src.primitives;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1206,7 +1332,12 @@ public:
|
||||||
sampler.clear();
|
sampler.clear();
|
||||||
qualifier = p.qualifier;
|
qualifier = p.qualifier;
|
||||||
if (p.userDef) {
|
if (p.userDef) {
|
||||||
structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues
|
if (p.userDef->basicType == EbtReference) {
|
||||||
|
basicType = EbtReference;
|
||||||
|
referentType = p.userDef->referentType;
|
||||||
|
} else {
|
||||||
|
structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues
|
||||||
|
}
|
||||||
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1275,6 +1406,17 @@ public:
|
||||||
sampler.clear();
|
sampler.clear();
|
||||||
typeName = NewPoolTString(n.c_str());
|
typeName = NewPoolTString(n.c_str());
|
||||||
}
|
}
|
||||||
|
// for block reference (first parameter must be EbtReference)
|
||||||
|
explicit TType(TBasicType t, const TType &p, const TString& n) :
|
||||||
|
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
|
||||||
|
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
|
||||||
|
{
|
||||||
|
assert(t == EbtReference);
|
||||||
|
typeName = NewPoolTString(n.c_str());
|
||||||
|
qualifier.clear();
|
||||||
|
qualifier.storage = p.qualifier.storage;
|
||||||
|
referentType = p.clone();
|
||||||
|
}
|
||||||
virtual ~TType() {}
|
virtual ~TType() {}
|
||||||
|
|
||||||
// Not for use across pool pops; it will cause multiple instances of TType to point to the same information.
|
// Not for use across pool pops; it will cause multiple instances of TType to point to the same information.
|
||||||
|
@ -1290,9 +1432,13 @@ public:
|
||||||
matrixRows = copyOf.matrixRows;
|
matrixRows = copyOf.matrixRows;
|
||||||
vector1 = copyOf.vector1;
|
vector1 = copyOf.vector1;
|
||||||
arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents
|
arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents
|
||||||
structure = copyOf.structure;
|
|
||||||
fieldName = copyOf.fieldName;
|
fieldName = copyOf.fieldName;
|
||||||
typeName = copyOf.typeName;
|
typeName = copyOf.typeName;
|
||||||
|
if (isStruct()) {
|
||||||
|
structure = copyOf.structure;
|
||||||
|
} else {
|
||||||
|
referentType = copyOf.referentType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make complete copy of the whole type graph rooted at 'copyOf'.
|
// Make complete copy of the whole type graph rooted at 'copyOf'.
|
||||||
|
@ -1355,6 +1501,7 @@ public:
|
||||||
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
|
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
|
||||||
virtual const TArraySizes* getArraySizes() const { return arraySizes; }
|
virtual const TArraySizes* getArraySizes() const { return arraySizes; }
|
||||||
virtual TArraySizes* getArraySizes() { return arraySizes; }
|
virtual TArraySizes* getArraySizes() { return arraySizes; }
|
||||||
|
virtual TType* getReferentType() const { return referentType; }
|
||||||
|
|
||||||
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
|
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
|
||||||
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
|
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
|
||||||
|
@ -1366,7 +1513,7 @@ public:
|
||||||
virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
|
virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
|
||||||
virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
|
virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
|
||||||
virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
|
virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
|
||||||
virtual bool isStruct() const { return structure != nullptr; }
|
virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; }
|
||||||
virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
|
virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
|
||||||
virtual bool isIntegerDomain() const
|
virtual bool isIntegerDomain() const
|
||||||
{
|
{
|
||||||
|
@ -1386,7 +1533,11 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint; }
|
virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
|| basicType == EbtAccStructNV
|
||||||
|
#endif
|
||||||
|
; }
|
||||||
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
|
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
|
||||||
|
|
||||||
// "Image" is a superset of "Subpass"
|
// "Image" is a superset of "Subpass"
|
||||||
|
@ -1403,7 +1554,7 @@ public:
|
||||||
|
|
||||||
const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); };
|
const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); };
|
||||||
|
|
||||||
return structure && std::any_of(structure->begin(), structure->end(), hasa);
|
return isStruct() && std::any_of(structure->begin(), structure->end(), hasa);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively checks if the type contains the given basic type
|
// Recursively checks if the type contains the given basic type
|
||||||
|
@ -1540,6 +1691,11 @@ public:
|
||||||
{
|
{
|
||||||
if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed()))
|
if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed()))
|
||||||
changeOuterArraySize(getImplicitArraySize());
|
changeOuterArraySize(getImplicitArraySize());
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// For multi-dim per-view arrays, set unsized inner dimension size to 1
|
||||||
|
if (qualifier.isPerView() && arraySizes && arraySizes->isInnerUnsized())
|
||||||
|
arraySizes->clearInnerUnsized();
|
||||||
|
#endif
|
||||||
if (isStruct() && structure->size() > 0) {
|
if (isStruct() && structure->size() > 0) {
|
||||||
int lastMember = (int)structure->size() - 1;
|
int lastMember = (int)structure->size() - 1;
|
||||||
for (int i = 0; i < lastMember; ++i)
|
for (int i = 0; i < lastMember; ++i)
|
||||||
|
@ -1574,6 +1730,10 @@ public:
|
||||||
case EbtSampler: return "sampler/image";
|
case EbtSampler: return "sampler/image";
|
||||||
case EbtStruct: return "structure";
|
case EbtStruct: return "structure";
|
||||||
case EbtBlock: return "block";
|
case EbtBlock: return "block";
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EbtAccStructNV: return "accelerationStructureNV";
|
||||||
|
#endif
|
||||||
|
case EbtReference: return "reference";
|
||||||
default: return "unknown type";
|
default: return "unknown type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1659,6 +1819,12 @@ public:
|
||||||
}
|
}
|
||||||
if (qualifier.layoutPushConstant)
|
if (qualifier.layoutPushConstant)
|
||||||
appendStr(" push_constant");
|
appendStr(" push_constant");
|
||||||
|
if (qualifier.layoutBufferReference)
|
||||||
|
appendStr(" buffer_reference");
|
||||||
|
if (qualifier.hasBufferReferenceAlign()) {
|
||||||
|
appendStr(" buffer_reference_align=");
|
||||||
|
appendUint(1u << qualifier.layoutBufferReferenceAlign);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (qualifier.layoutPassthrough)
|
if (qualifier.layoutPassthrough)
|
||||||
|
@ -1669,6 +1835,8 @@ public:
|
||||||
appendStr(" layoutSecondaryViewportRelativeOffset=");
|
appendStr(" layoutSecondaryViewportRelativeOffset=");
|
||||||
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
|
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
|
||||||
}
|
}
|
||||||
|
if (qualifier.layoutShaderRecordNV)
|
||||||
|
appendStr(" shaderRecordNV");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
appendStr(")");
|
appendStr(")");
|
||||||
|
@ -1690,6 +1858,16 @@ public:
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
if (qualifier.explicitInterp)
|
if (qualifier.explicitInterp)
|
||||||
appendStr(" __explicitInterpAMD");
|
appendStr(" __explicitInterpAMD");
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (qualifier.pervertexNV)
|
||||||
|
appendStr(" pervertexNV");
|
||||||
|
if (qualifier.perPrimitiveNV)
|
||||||
|
appendStr(" perprimitiveNV");
|
||||||
|
if (qualifier.perViewNV)
|
||||||
|
appendStr(" perviewNV");
|
||||||
|
if (qualifier.perTaskNV)
|
||||||
|
appendStr(" taskNV");
|
||||||
#endif
|
#endif
|
||||||
if (qualifier.patch)
|
if (qualifier.patch)
|
||||||
appendStr(" patch");
|
appendStr(" patch");
|
||||||
|
@ -1697,6 +1875,16 @@ public:
|
||||||
appendStr(" sample");
|
appendStr(" sample");
|
||||||
if (qualifier.coherent)
|
if (qualifier.coherent)
|
||||||
appendStr(" coherent");
|
appendStr(" coherent");
|
||||||
|
if (qualifier.devicecoherent)
|
||||||
|
appendStr(" devicecoherent");
|
||||||
|
if (qualifier.queuefamilycoherent)
|
||||||
|
appendStr(" queuefamilycoherent");
|
||||||
|
if (qualifier.workgroupcoherent)
|
||||||
|
appendStr(" workgroupcoherent");
|
||||||
|
if (qualifier.subgroupcoherent)
|
||||||
|
appendStr(" subgroupcoherent");
|
||||||
|
if (qualifier.nonprivate)
|
||||||
|
appendStr(" nonprivate");
|
||||||
if (qualifier.volatil)
|
if (qualifier.volatil)
|
||||||
appendStr(" volatile");
|
appendStr(" volatile");
|
||||||
if (qualifier.restrict)
|
if (qualifier.restrict)
|
||||||
|
@ -1756,7 +1944,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add struct/block members
|
// Add struct/block members
|
||||||
if (structure) {
|
if (isStruct()) {
|
||||||
appendStr("{");
|
appendStr("{");
|
||||||
for (size_t i = 0; i < structure->size(); ++i) {
|
for (size_t i = 0; i < structure->size(); ++i) {
|
||||||
if (! (*structure)[i].type->hiddenMember()) {
|
if (! (*structure)[i].type->hiddenMember()) {
|
||||||
|
@ -1784,9 +1972,9 @@ public:
|
||||||
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
|
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
|
||||||
const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
|
const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
|
||||||
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
|
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
|
||||||
const TTypeList* getStruct() const { return structure; }
|
const TTypeList* getStruct() const { assert(isStruct()); return structure; }
|
||||||
void setStruct(TTypeList* s) { structure = s; }
|
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
|
||||||
TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads
|
TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads
|
||||||
|
|
||||||
int computeNumComponents() const
|
int computeNumComponents() const
|
||||||
{
|
{
|
||||||
|
@ -1825,11 +2013,12 @@ public:
|
||||||
bool sameStructType(const TType& right) const
|
bool sameStructType(const TType& right) const
|
||||||
{
|
{
|
||||||
// Most commonly, they are both nullptr, or the same pointer to the same actual structure
|
// Most commonly, they are both nullptr, or the same pointer to the same actual structure
|
||||||
if (structure == right.structure)
|
if ((!isStruct() && !right.isStruct()) ||
|
||||||
|
(isStruct() && right.isStruct() && structure == right.structure))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
|
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
|
||||||
if (structure == nullptr || right.structure == nullptr ||
|
if (!isStruct() || !right.isStruct() ||
|
||||||
structure->size() != right.structure->size())
|
structure->size() != right.structure->size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1849,6 +2038,23 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sameReferenceType(const TType& right) const
|
||||||
|
{
|
||||||
|
if ((basicType == EbtReference) != (right.basicType == EbtReference))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((basicType != EbtReference) && (right.basicType != EbtReference))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
assert(referentType != nullptr);
|
||||||
|
assert(right.referentType != nullptr);
|
||||||
|
|
||||||
|
if (referentType == right.referentType)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return *referentType == *right.referentType;
|
||||||
|
}
|
||||||
|
|
||||||
// See if two types match, in all aspects except arrayness
|
// See if two types match, in all aspects except arrayness
|
||||||
bool sameElementType(const TType& right) const
|
bool sameElementType(const TType& right) const
|
||||||
{
|
{
|
||||||
|
@ -1877,7 +2083,8 @@ public:
|
||||||
matrixCols == right.matrixCols &&
|
matrixCols == right.matrixCols &&
|
||||||
matrixRows == right.matrixRows &&
|
matrixRows == right.matrixRows &&
|
||||||
vector1 == right.vector1 &&
|
vector1 == right.vector1 &&
|
||||||
sameStructType(right);
|
sameStructType(right) &&
|
||||||
|
sameReferenceType(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if two types match in all ways (just the actual type, not qualification)
|
// See if two types match in all ways (just the actual type, not qualification)
|
||||||
|
@ -1908,7 +2115,7 @@ protected:
|
||||||
*arraySizes = *copyOf.arraySizes;
|
*arraySizes = *copyOf.arraySizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copyOf.structure) {
|
if (copyOf.isStruct() && copyOf.structure) {
|
||||||
auto prevCopy = copiedMap.find(copyOf.structure);
|
auto prevCopy = copiedMap.find(copyOf.structure);
|
||||||
if (prevCopy != copiedMap.end())
|
if (prevCopy != copiedMap.end())
|
||||||
structure = prevCopy->second;
|
structure = prevCopy->second;
|
||||||
|
@ -1946,7 +2153,12 @@ protected:
|
||||||
TQualifier qualifier;
|
TQualifier qualifier;
|
||||||
|
|
||||||
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types
|
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types
|
||||||
TTypeList* structure; // nullptr unless this is a struct; can be shared across types
|
// A type can't be both a structure (EbtStruct/EbtBlock) and a reference (EbtReference), so
|
||||||
|
// conserve space by making these a union
|
||||||
|
union {
|
||||||
|
TTypeList* structure; // invalid unless this is a struct; can be shared across types
|
||||||
|
TType *referentType; // invalid unless this is an EbtReference
|
||||||
|
};
|
||||||
TString *fieldName; // for structure field names
|
TString *fieldName; // for structure field names
|
||||||
TString *typeName; // for structure type name
|
TString *typeName; // for structure type name
|
||||||
TSampler sampler;
|
TSampler sampler;
|
||||||
|
|
|
@ -269,6 +269,10 @@ enum TOperator {
|
||||||
EOpConvDoubleToFloat16,
|
EOpConvDoubleToFloat16,
|
||||||
EOpConvDoubleToFloat,
|
EOpConvDoubleToFloat,
|
||||||
|
|
||||||
|
// uint64_t <-> pointer
|
||||||
|
EOpConvUint64ToPtr,
|
||||||
|
EOpConvPtrToUint64,
|
||||||
|
|
||||||
//
|
//
|
||||||
// binary operations
|
// binary operations
|
||||||
//
|
//
|
||||||
|
@ -592,6 +596,8 @@ enum TOperator {
|
||||||
EOpAtomicXor,
|
EOpAtomicXor,
|
||||||
EOpAtomicExchange,
|
EOpAtomicExchange,
|
||||||
EOpAtomicCompSwap,
|
EOpAtomicCompSwap,
|
||||||
|
EOpAtomicLoad,
|
||||||
|
EOpAtomicStore,
|
||||||
|
|
||||||
EOpAtomicCounterIncrement, // results in pre-increment value
|
EOpAtomicCounterIncrement, // results in pre-increment value
|
||||||
EOpAtomicCounterDecrement, // results in post-decrement value
|
EOpAtomicCounterDecrement, // results in post-decrement value
|
||||||
|
@ -730,6 +736,7 @@ enum TOperator {
|
||||||
EOpConstructStruct,
|
EOpConstructStruct,
|
||||||
EOpConstructTextureSampler,
|
EOpConstructTextureSampler,
|
||||||
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
|
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
|
||||||
|
EOpConstructReference,
|
||||||
EOpConstructGuardEnd,
|
EOpConstructGuardEnd,
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -784,6 +791,8 @@ enum TOperator {
|
||||||
EOpImageAtomicXor,
|
EOpImageAtomicXor,
|
||||||
EOpImageAtomicExchange,
|
EOpImageAtomicExchange,
|
||||||
EOpImageAtomicCompSwap,
|
EOpImageAtomicCompSwap,
|
||||||
|
EOpImageAtomicLoad,
|
||||||
|
EOpImageAtomicStore,
|
||||||
|
|
||||||
EOpSubpassLoad,
|
EOpSubpassLoad,
|
||||||
EOpSubpassLoadMS,
|
EOpSubpassLoadMS,
|
||||||
|
@ -861,6 +870,16 @@ enum TOperator {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EOpSparseTextureGuardEnd,
|
EOpSparseTextureGuardEnd,
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
EOpImageFootprintGuardBegin,
|
||||||
|
EOpImageSampleFootprintNV,
|
||||||
|
EOpImageSampleFootprintClampNV,
|
||||||
|
EOpImageSampleFootprintLodNV,
|
||||||
|
EOpImageSampleFootprintGradNV,
|
||||||
|
EOpImageSampleFootprintGradClampNV,
|
||||||
|
EOpImageFootprintGuardEnd,
|
||||||
|
#endif
|
||||||
EOpSamplingGuardEnd,
|
EOpSamplingGuardEnd,
|
||||||
EOpTextureGuardEnd,
|
EOpTextureGuardEnd,
|
||||||
|
|
||||||
|
@ -879,6 +898,14 @@ enum TOperator {
|
||||||
EOpFindLSB,
|
EOpFindLSB,
|
||||||
EOpFindMSB,
|
EOpFindMSB,
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
EOpTraceNV,
|
||||||
|
EOpReportIntersectionNV,
|
||||||
|
EOpIgnoreIntersectionNV,
|
||||||
|
EOpTerminateRayNV,
|
||||||
|
EOpExecuteCallableNV,
|
||||||
|
EOpWritePackedPrimitiveIndices4x8NV,
|
||||||
|
#endif
|
||||||
//
|
//
|
||||||
// HLSL operations
|
// HLSL operations
|
||||||
//
|
//
|
||||||
|
@ -1164,6 +1191,7 @@ public:
|
||||||
constSubtree(nullptr)
|
constSubtree(nullptr)
|
||||||
{ name = n; }
|
{ name = n; }
|
||||||
virtual int getId() const { return id; }
|
virtual int getId() const { return id; }
|
||||||
|
virtual void changeId(int i) { id = i; }
|
||||||
virtual const TString& getName() const { return name; }
|
virtual const TString& getName() const { return name; }
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermSymbol* getAsSymbolNode() { return this; }
|
virtual TIntermSymbol* getAsSymbolNode() { return this; }
|
||||||
|
@ -1243,6 +1271,9 @@ public:
|
||||||
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
|
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
|
||||||
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
|
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
|
||||||
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
|
||||||
|
#endif
|
||||||
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
||||||
|
|
||||||
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
|
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
|
||||||
|
@ -1415,6 +1446,23 @@ public:
|
||||||
cracked.subpass = sampler.dim == EsdSubpass;
|
cracked.subpass = sampler.dim == EsdSubpass;
|
||||||
cracked.fragMask = true;
|
cracked.fragMask = true;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EOpImageSampleFootprintNV:
|
||||||
|
break;
|
||||||
|
case EOpImageSampleFootprintClampNV:
|
||||||
|
cracked.lodClamp = true;
|
||||||
|
break;
|
||||||
|
case EOpImageSampleFootprintLodNV:
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
case EOpImageSampleFootprintGradNV:
|
||||||
|
cracked.grad = true;
|
||||||
|
break;
|
||||||
|
case EOpImageSampleFootprintGradClampNV:
|
||||||
|
cracked.lodClamp = true;
|
||||||
|
cracked.grad = true;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case EOpSubpassLoad:
|
case EOpSubpassLoad:
|
||||||
case EOpSubpassLoadMS:
|
case EOpSubpassLoadMS:
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
// This header is generated by the make-revision script.
|
// This header is generated by the make-revision script.
|
||||||
|
|
||||||
#define GLSLANG_PATCH_LEVEL 2801
|
#define GLSLANG_PATCH_LEVEL 3057
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -184,7 +185,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
else if (leftUnionArray[i].getDConst() > 0.0)
|
else if (leftUnionArray[i].getDConst() > 0.0)
|
||||||
newConstArray[i].setDConst((double)INFINITY);
|
newConstArray[i].setDConst((double)INFINITY);
|
||||||
else if (leftUnionArray[i].getDConst() < 0.0)
|
else if (leftUnionArray[i].getDConst() < 0.0)
|
||||||
newConstArray[i].setDConst((double)-INFINITY);
|
newConstArray[i].setDConst(-(double)INFINITY);
|
||||||
else
|
else
|
||||||
newConstArray[i].setDConst((double)NAN);
|
newConstArray[i].setDConst((double)NAN);
|
||||||
break;
|
break;
|
||||||
|
@ -223,8 +224,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
if (rightUnionArray[i] == 0)
|
if (rightUnionArray[i] == 0)
|
||||||
newConstArray[i].setIConst(0x7FFFFFFF);
|
newConstArray[i].setIConst(0x7FFFFFFF);
|
||||||
else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == -(int)0x80000000)
|
else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)-0x80000000ll)
|
||||||
newConstArray[i].setIConst(-(int)0x80000000);
|
newConstArray[i].setIConst((int)-0x80000000ll);
|
||||||
else
|
else
|
||||||
newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
|
newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
|
||||||
break;
|
break;
|
||||||
|
@ -239,8 +240,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (rightUnionArray[i] == 0ll)
|
if (rightUnionArray[i] == 0ll)
|
||||||
newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
|
newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
|
||||||
else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == -0x8000000000000000ll)
|
else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)-0x8000000000000000ll)
|
||||||
newConstArray[i].setI64Const(-0x8000000000000000ll);
|
newConstArray[i].setI64Const((long long)-0x8000000000000000ll);
|
||||||
else
|
else
|
||||||
newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const());
|
newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const());
|
||||||
break;
|
break;
|
||||||
|
@ -670,6 +671,279 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EOpConvInt8ToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
|
||||||
|
case EOpConvUint8ToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getU8Const() != 0); break;
|
||||||
|
case EOpConvInt16ToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break;
|
||||||
|
case EOpConvUint16ToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break;
|
||||||
|
case EOpConvIntToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break;
|
||||||
|
case EOpConvUintToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break;
|
||||||
|
case EOpConvInt64ToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
||||||
|
case EOpConvUint64ToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
||||||
|
case EOpConvFloat16ToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
||||||
|
case EOpConvFloatToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
||||||
|
case EOpConvDoubleToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
||||||
|
|
||||||
|
case EOpConvBoolToInt8:
|
||||||
|
newConstArray[i].setI8Const(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToUint8:
|
||||||
|
newConstArray[i].setU8Const(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToInt16:
|
||||||
|
newConstArray[i].setI16Const(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToUint16:
|
||||||
|
newConstArray[i].setU16Const(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
||||||
|
|
||||||
|
case EOpConvInt8ToInt16:
|
||||||
|
newConstArray[i].setI16Const(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToUint8:
|
||||||
|
newConstArray[i].setU8Const(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToUint16:
|
||||||
|
newConstArray[i].setU16Const(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvUint8ToInt8:
|
||||||
|
newConstArray[i].setI8Const(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToInt16:
|
||||||
|
newConstArray[i].setI16Const(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToUint16:
|
||||||
|
newConstArray[i].setU16Const(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvInt8ToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvInt8ToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
|
||||||
|
case EOpConvUint8ToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
|
||||||
|
case EOpConvUint8ToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
|
||||||
|
|
||||||
|
case EOpConvInt16ToInt8:
|
||||||
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI16Const())); break;
|
||||||
|
case EOpConvInt16ToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvInt16ToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvInt16ToUint8:
|
||||||
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getI16Const())); break;
|
||||||
|
case EOpConvInt16ToUint16:
|
||||||
|
newConstArray[i].setU16Const(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvInt16ToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvInt16ToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvUint16ToInt8:
|
||||||
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getU16Const())); break;
|
||||||
|
case EOpConvUint16ToInt16:
|
||||||
|
newConstArray[i].setI16Const(unionArray[i].getU16Const()); break;
|
||||||
|
case EOpConvUint16ToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getU16Const()); break;
|
||||||
|
case EOpConvUint16ToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getU16Const()); break;
|
||||||
|
case EOpConvUint16ToUint8:
|
||||||
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getU16Const())); break;
|
||||||
|
|
||||||
|
case EOpConvUint16ToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getU16Const()); break;
|
||||||
|
case EOpConvUint16ToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getU16Const()); break;
|
||||||
|
case EOpConvInt16ToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvInt16ToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvInt16ToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
|
||||||
|
case EOpConvUint16ToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
|
||||||
|
case EOpConvUint16ToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
|
||||||
|
case EOpConvUint16ToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
|
||||||
|
|
||||||
|
case EOpConvIntToInt8:
|
||||||
|
newConstArray[i].setI8Const((signed char)unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToInt16:
|
||||||
|
newConstArray[i].setI16Const((signed short)unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToUint8:
|
||||||
|
newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToUint16:
|
||||||
|
newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getIConst()); break;
|
||||||
|
|
||||||
|
case EOpConvUintToInt8:
|
||||||
|
newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToInt16:
|
||||||
|
newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToUint8:
|
||||||
|
newConstArray[i].setU8Const((unsigned char)unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToUint16:
|
||||||
|
newConstArray[i].setU16Const((unsigned short)unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvIntToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvIntToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvUintToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvUintToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
||||||
|
case EOpConvInt64ToInt8:
|
||||||
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToInt16:
|
||||||
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToInt:
|
||||||
|
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToUint8:
|
||||||
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToUint16:
|
||||||
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToUint:
|
||||||
|
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToUint64:
|
||||||
|
newConstArray[i].setU64Const(unionArray[i].getI64Const()); break;
|
||||||
|
case EOpConvUint64ToInt8:
|
||||||
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvUint64ToInt16:
|
||||||
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvUint64ToInt:
|
||||||
|
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvUint64ToInt64:
|
||||||
|
newConstArray[i].setI64Const(unionArray[i].getU64Const()); break;
|
||||||
|
case EOpConvUint64ToUint8:
|
||||||
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvUint64ToUint16:
|
||||||
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvUint64ToUint:
|
||||||
|
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvInt64ToFloat16:
|
||||||
|
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToFloat:
|
||||||
|
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvInt64ToDouble:
|
||||||
|
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
|
||||||
|
case EOpConvUint64ToFloat16:
|
||||||
|
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvUint64ToFloat:
|
||||||
|
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvUint64ToDouble:
|
||||||
|
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
|
||||||
|
case EOpConvFloat16ToInt8:
|
||||||
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToInt16:
|
||||||
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToInt:
|
||||||
|
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToInt64:
|
||||||
|
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToUint8:
|
||||||
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToUint16:
|
||||||
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToUint:
|
||||||
|
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToUint64:
|
||||||
|
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloat16ToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
|
case EOpConvFloat16ToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
|
case EOpConvFloatToInt8:
|
||||||
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToInt16:
|
||||||
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToInt:
|
||||||
|
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToInt64:
|
||||||
|
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToUint8:
|
||||||
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToUint16:
|
||||||
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToUint:
|
||||||
|
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToUint64:
|
||||||
|
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvFloatToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
|
case EOpConvFloatToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
|
case EOpConvDoubleToInt8:
|
||||||
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToInt16:
|
||||||
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToInt:
|
||||||
|
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToInt64:
|
||||||
|
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToUint8:
|
||||||
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToUint16:
|
||||||
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToUint:
|
||||||
|
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToUint64:
|
||||||
|
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
||||||
|
case EOpConvDoubleToFloat16:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
|
case EOpConvDoubleToFloat:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
|
// TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
|
||||||
|
|
||||||
case EOpSinh:
|
case EOpSinh:
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2015 LunarG, Inc.
|
// Copyright (C) 2012-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2016 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
@ -460,6 +460,9 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
|
||||||
return false;
|
return false;
|
||||||
case EbtAtomicUint:
|
case EbtAtomicUint:
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EbtAccStructNV:
|
||||||
|
#endif
|
||||||
// opaque types can be passed to functions
|
// opaque types can be passed to functions
|
||||||
if (op == EOpFunction)
|
if (op == EOpFunction)
|
||||||
break;
|
break;
|
||||||
|
@ -486,7 +489,7 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
|
||||||
// This is 'mechanism' here, it does any conversion told.
|
// This is 'mechanism' here, it does any conversion told.
|
||||||
// It is about basic type, not about shape.
|
// It is about basic type, not about shape.
|
||||||
// The policy comes from the shader or the calling code.
|
// The policy comes from the shader or the calling code.
|
||||||
TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const
|
TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Add a new newNode for the conversion.
|
// Add a new newNode for the conversion.
|
||||||
|
@ -709,7 +712,11 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped
|
||||||
TType newType(convertTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
|
TType newType(convertTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
|
||||||
newNode = addUnaryNode(newOp, node, node->getLoc(), newType);
|
newNode = addUnaryNode(newOp, node, node->getLoc(), newType);
|
||||||
|
|
||||||
// TODO: it seems that some unary folding operations should occur here, but are not
|
if (node->getAsConstantUnion()) {
|
||||||
|
TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType);
|
||||||
|
if (folded)
|
||||||
|
return folded;
|
||||||
|
}
|
||||||
|
|
||||||
// Propagate specialization-constant-ness, if allowed
|
// Propagate specialization-constant-ness, if allowed
|
||||||
if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode))
|
if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode))
|
||||||
|
@ -900,28 +907,28 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||||
break;
|
break;
|
||||||
case EOpConstructFloat16:
|
case EOpConstructFloat16:
|
||||||
promoteTo = EbtFloat16;
|
promoteTo = EbtFloat16;
|
||||||
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float16);
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16);
|
||||||
break;
|
break;
|
||||||
case EOpConstructInt8:
|
case EOpConstructInt8:
|
||||||
promoteTo = EbtInt8;
|
promoteTo = EbtInt8;
|
||||||
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int8);
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
|
||||||
break;
|
break;
|
||||||
case EOpConstructUint8:
|
case EOpConstructUint8:
|
||||||
promoteTo = EbtUint8;
|
promoteTo = EbtUint8;
|
||||||
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int8);
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
|
||||||
break;
|
break;
|
||||||
case EOpConstructInt16:
|
case EOpConstructInt16:
|
||||||
promoteTo = EbtInt16;
|
promoteTo = EbtInt16;
|
||||||
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int16);
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
|
||||||
break;
|
break;
|
||||||
case EOpConstructUint16:
|
case EOpConstructUint16:
|
||||||
promoteTo = EbtUint16;
|
promoteTo = EbtUint16;
|
||||||
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int16);
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
|
||||||
break;
|
break;
|
||||||
case EOpConstructInt:
|
case EOpConstructInt:
|
||||||
promoteTo = EbtInt;
|
promoteTo = EbtInt;
|
||||||
|
@ -977,6 +984,14 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||||
case EOpSequence:
|
case EOpSequence:
|
||||||
case EOpConstructStruct:
|
case EOpConstructStruct:
|
||||||
|
|
||||||
|
if (type.getBasicType() == EbtReference || node->getType().getBasicType() == EbtReference) {
|
||||||
|
// types must match to assign a reference
|
||||||
|
if (type == node->getType())
|
||||||
|
return node;
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (type.getBasicType() == node->getType().getBasicType())
|
if (type.getBasicType() == node->getType().getBasicType())
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
|
@ -1018,7 +1033,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||||
//
|
//
|
||||||
// Add a new newNode for the conversion.
|
// Add a new newNode for the conversion.
|
||||||
//
|
//
|
||||||
TIntermUnary* newNode = createConversion(promoteTo, node);
|
TIntermTyped* newNode = createConversion(promoteTo, node);
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
@ -1116,9 +1131,12 @@ void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, T
|
||||||
rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
|
rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case EOpMul:
|
||||||
|
// matrix multiply does not change shapes
|
||||||
|
if (lhsNode->isMatrix() && rhsNode->isMatrix())
|
||||||
|
return;
|
||||||
case EOpAdd:
|
case EOpAdd:
|
||||||
case EOpSub:
|
case EOpSub:
|
||||||
case EOpMul:
|
|
||||||
case EOpDiv:
|
case EOpDiv:
|
||||||
// want to support vector * scalar native ops in AST and lower, not smear, similarly for
|
// want to support vector * scalar native ops in AST and lower, not smear, similarly for
|
||||||
// matrix * vector, etc.
|
// matrix * vector, etc.
|
||||||
|
@ -1191,9 +1209,19 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped*
|
||||||
// The new node that handles the conversion
|
// The new node that handles the conversion
|
||||||
TOperator constructorOp = mapTypeToConstructorOp(type);
|
TOperator constructorOp = mapTypeToConstructorOp(type);
|
||||||
|
|
||||||
// HLSL has custom semantics for scalar->mat shape conversions.
|
|
||||||
if (source == EShSourceHlsl) {
|
if (source == EShSourceHlsl) {
|
||||||
if (node->getType().isScalarOrVec1() && type.isMatrix()) {
|
// HLSL rules for scalar, vector and matrix conversions:
|
||||||
|
// 1) scalar can become anything, initializing every component with its value
|
||||||
|
// 2) vector and matrix can become scalar, first element is used (warning: truncation)
|
||||||
|
// 3) matrix can become matrix with less rows and/or columns (warning: truncation)
|
||||||
|
// 4) vector can become vector with less rows size (warning: truncation)
|
||||||
|
// 5a) vector 4 can become 2x2 matrix (special case) (same packing layout, its a reinterpret)
|
||||||
|
// 5b) 2x2 matrix can become vector 4 (special case) (same packing layout, its a reinterpret)
|
||||||
|
|
||||||
|
const TType &sourceType = node->getType();
|
||||||
|
|
||||||
|
// rule 1 for scalar to matrix is special
|
||||||
|
if (sourceType.isScalarOrVec1() && type.isMatrix()) {
|
||||||
|
|
||||||
// HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its
|
// HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its
|
||||||
// own devices, the constructor from a scalar would populate the diagonal. This forces replication
|
// own devices, the constructor from a scalar would populate the diagonal. This forces replication
|
||||||
|
@ -1201,7 +1229,7 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped*
|
||||||
|
|
||||||
// Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
|
// Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
|
||||||
// repeatedly, so we copy it to a temp, then use the temp.
|
// repeatedly, so we copy it to a temp, then use the temp.
|
||||||
const int matSize = type.getMatrixRows() * type.getMatrixCols();
|
const int matSize = type.computeNumComponents();
|
||||||
TIntermAggregate* rhsAggregate = new TIntermAggregate();
|
TIntermAggregate* rhsAggregate = new TIntermAggregate();
|
||||||
|
|
||||||
const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);
|
const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);
|
||||||
|
@ -1209,12 +1237,44 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped*
|
||||||
if (!isSimple) {
|
if (!isSimple) {
|
||||||
assert(0); // TODO: use node replicator service when available.
|
assert(0); // TODO: use node replicator service when available.
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x=0; x<matSize; ++x)
|
for (int x = 0; x < matSize; ++x)
|
||||||
rhsAggregate->getSequence().push_back(node);
|
rhsAggregate->getSequence().push_back(node);
|
||||||
|
|
||||||
return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
|
return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rule 1 and 2
|
||||||
|
if ((sourceType.isScalar() && !type.isScalar()) || (!sourceType.isScalar() && type.isScalar()))
|
||||||
|
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
|
||||||
|
|
||||||
|
// rule 3 and 5b
|
||||||
|
if (sourceType.isMatrix()) {
|
||||||
|
// rule 3
|
||||||
|
if (type.isMatrix()) {
|
||||||
|
if ((sourceType.getMatrixCols() != type.getMatrixCols() || sourceType.getMatrixRows() != type.getMatrixRows()) &&
|
||||||
|
sourceType.getMatrixCols() >= type.getMatrixCols() && sourceType.getMatrixRows() >= type.getMatrixRows())
|
||||||
|
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
|
||||||
|
// rule 5b
|
||||||
|
} else if (type.isVector()) {
|
||||||
|
if (type.getVectorSize() == 4 && sourceType.getMatrixCols() == 2 && sourceType.getMatrixRows() == 2)
|
||||||
|
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rule 4 and 5a
|
||||||
|
if (sourceType.isVector()) {
|
||||||
|
// rule 4
|
||||||
|
if (type.isVector())
|
||||||
|
{
|
||||||
|
if (sourceType.getVectorSize() > type.getVectorSize())
|
||||||
|
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
|
||||||
|
// rule 5a
|
||||||
|
} else if (type.isMatrix()) {
|
||||||
|
if (sourceType.getVectorSize() == 4 && type.getMatrixCols() == 2 && type.getMatrixRows() == 2)
|
||||||
|
return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scalar -> vector or vec1 -> vector or
|
// scalar -> vector or vec1 -> vector or
|
||||||
|
@ -1433,14 +1493,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool explicitTypesEnabled = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
bool explicitTypesEnabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int8) ||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int16) ||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int32) ||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int32) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int64) ||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int64) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float16) ||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float32) ||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
|
||||||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float64);
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float64);
|
||||||
|
|
||||||
if (explicitTypesEnabled) {
|
if (explicitTypesEnabled) {
|
||||||
// integral promotions
|
// integral promotions
|
||||||
|
@ -1573,27 +1633,29 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
switch (from) {
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
switch (from) {
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_half_float);
|
return extensionRequested(E_GL_AMD_gpu_shader_half_float);
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
switch (from) {
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
switch (from) {
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2077,6 +2139,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EbtReference:
|
||||||
|
op = EOpConstructReference;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,12 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||||
if (node->getQualifier().readonly)
|
if (node->getQualifier().readonly)
|
||||||
message = "can't modify a readonly buffer";
|
message = "can't modify a readonly buffer";
|
||||||
break;
|
break;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EvqHitAttrNV:
|
||||||
|
if (language != EShLangIntersectNV)
|
||||||
|
message = "cannot modify hitAttributeNV in this stage";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//
|
//
|
||||||
|
@ -168,6 +174,11 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||||
case EbtVoid:
|
case EbtVoid:
|
||||||
message = "can't modify void";
|
message = "can't modify void";
|
||||||
break;
|
break;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EbtAccStructNV:
|
||||||
|
message = "can't modify accelerationStructureNV";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -298,14 +299,14 @@ public:
|
||||||
void fixIoArraySize(const TSourceLoc&, TType&);
|
void fixIoArraySize(const TSourceLoc&, TType&);
|
||||||
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
|
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
|
||||||
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
|
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false, bool isPerPrimitive = false);
|
||||||
int getIoArrayImplicitSize() const;
|
int getIoArrayImplicitSize(bool isPerPrimitive = false) const;
|
||||||
void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
|
void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
|
||||||
|
|
||||||
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
||||||
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
||||||
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||||
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, const TString& field);
|
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
|
||||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||||
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
|
@ -323,6 +324,7 @@ public:
|
||||||
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
||||||
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
|
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
|
||||||
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
||||||
|
void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
|
||||||
|
|
||||||
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
||||||
|
@ -347,6 +349,7 @@ public:
|
||||||
void boolCheck(const TSourceLoc&, const TPublicType&);
|
void boolCheck(const TSourceLoc&, const TPublicType&);
|
||||||
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
||||||
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
|
void accStructNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
|
||||||
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
void memberQualifierCheck(glslang::TPublicType&);
|
void memberQualifierCheck(glslang::TPublicType&);
|
||||||
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
|
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
|
||||||
|
@ -401,7 +404,7 @@ public:
|
||||||
void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
|
void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
|
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
|
||||||
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
||||||
void fixBlockXfbOffsets(TQualifier&, TTypeList&);
|
void fixXfbOffsets(TQualifier&, TTypeList&);
|
||||||
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
|
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
|
||||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
|
||||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||||
|
@ -422,6 +425,8 @@ public:
|
||||||
// Determine loop control from attributes
|
// Determine loop control from attributes
|
||||||
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
|
|
||||||
|
void resizeMeshViewDimension(const TSourceLoc&, TType&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
||||||
void inheritGlobalDefaults(TQualifier& dst) const;
|
void inheritGlobalDefaults(TQualifier& dst) const;
|
||||||
|
|
|
@ -380,6 +380,11 @@ void TScanContext::fillInKeywordMap()
|
||||||
(*KeywordMap)["varying"] = VARYING;
|
(*KeywordMap)["varying"] = VARYING;
|
||||||
(*KeywordMap)["buffer"] = BUFFER;
|
(*KeywordMap)["buffer"] = BUFFER;
|
||||||
(*KeywordMap)["coherent"] = COHERENT;
|
(*KeywordMap)["coherent"] = COHERENT;
|
||||||
|
(*KeywordMap)["devicecoherent"] = DEVICECOHERENT;
|
||||||
|
(*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT;
|
||||||
|
(*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT;
|
||||||
|
(*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT;
|
||||||
|
(*KeywordMap)["nonprivate"] = NONPRIVATE;
|
||||||
(*KeywordMap)["restrict"] = RESTRICT;
|
(*KeywordMap)["restrict"] = RESTRICT;
|
||||||
(*KeywordMap)["readonly"] = READONLY;
|
(*KeywordMap)["readonly"] = READONLY;
|
||||||
(*KeywordMap)["writeonly"] = WRITEONLY;
|
(*KeywordMap)["writeonly"] = WRITEONLY;
|
||||||
|
@ -466,7 +471,7 @@ void TScanContext::fillInKeywordMap()
|
||||||
(*KeywordMap)["u64vec3"] = U64VEC3;
|
(*KeywordMap)["u64vec3"] = U64VEC3;
|
||||||
(*KeywordMap)["u64vec4"] = U64VEC4;
|
(*KeywordMap)["u64vec4"] = U64VEC4;
|
||||||
|
|
||||||
// GL_KHX_shader_explicit_arithmetic_types
|
// GL_EXT_shader_explicit_arithmetic_types
|
||||||
(*KeywordMap)["int8_t"] = INT8_T;
|
(*KeywordMap)["int8_t"] = INT8_T;
|
||||||
(*KeywordMap)["i8vec2"] = I8VEC2;
|
(*KeywordMap)["i8vec2"] = I8VEC2;
|
||||||
(*KeywordMap)["i8vec3"] = I8VEC3;
|
(*KeywordMap)["i8vec3"] = I8VEC3;
|
||||||
|
@ -587,6 +592,8 @@ void TScanContext::fillInKeywordMap()
|
||||||
|
|
||||||
(*KeywordMap)["samplerExternalOES"] = SAMPLEREXTERNALOES; // GL_OES_EGL_image_external
|
(*KeywordMap)["samplerExternalOES"] = SAMPLEREXTERNALOES; // GL_OES_EGL_image_external
|
||||||
|
|
||||||
|
(*KeywordMap)["__samplerExternal2DY2YEXT"] = SAMPLEREXTERNAL2DY2YEXT; // GL_EXT_YUV_target
|
||||||
|
|
||||||
(*KeywordMap)["sampler"] = SAMPLER;
|
(*KeywordMap)["sampler"] = SAMPLER;
|
||||||
(*KeywordMap)["samplerShadow"] = SAMPLERSHADOW;
|
(*KeywordMap)["samplerShadow"] = SAMPLERSHADOW;
|
||||||
|
|
||||||
|
@ -683,15 +690,30 @@ void TScanContext::fillInKeywordMap()
|
||||||
(*KeywordMap)["smooth"] = SMOOTH;
|
(*KeywordMap)["smooth"] = SMOOTH;
|
||||||
(*KeywordMap)["flat"] = FLAT;
|
(*KeywordMap)["flat"] = FLAT;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
(*KeywordMap)["__explicitInterpAMD"] = __EXPLICITINTERPAMD;
|
(*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD;
|
||||||
#endif
|
#endif
|
||||||
(*KeywordMap)["centroid"] = CENTROID;
|
(*KeywordMap)["centroid"] = CENTROID;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
(*KeywordMap)["pervertexNV"] = PERVERTEXNV;
|
||||||
|
#endif
|
||||||
(*KeywordMap)["precise"] = PRECISE;
|
(*KeywordMap)["precise"] = PRECISE;
|
||||||
(*KeywordMap)["invariant"] = INVARIANT;
|
(*KeywordMap)["invariant"] = INVARIANT;
|
||||||
(*KeywordMap)["packed"] = PACKED;
|
(*KeywordMap)["packed"] = PACKED;
|
||||||
(*KeywordMap)["resource"] = RESOURCE;
|
(*KeywordMap)["resource"] = RESOURCE;
|
||||||
(*KeywordMap)["superp"] = SUPERP;
|
(*KeywordMap)["superp"] = SUPERP;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
(*KeywordMap)["rayPayloadNV"] = PAYLOADNV;
|
||||||
|
(*KeywordMap)["rayPayloadInNV"] = PAYLOADINNV;
|
||||||
|
(*KeywordMap)["hitAttributeNV"] = HITATTRNV;
|
||||||
|
(*KeywordMap)["callableDataNV"] = CALLDATANV;
|
||||||
|
(*KeywordMap)["callableDataInNV"] = CALLDATAINNV;
|
||||||
|
(*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV;
|
||||||
|
(*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV;
|
||||||
|
(*KeywordMap)["perviewNV"] = PERVIEWNV;
|
||||||
|
(*KeywordMap)["taskNV"] = PERTASKNV;
|
||||||
|
#endif
|
||||||
|
|
||||||
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
|
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
|
||||||
|
|
||||||
ReservedSet->insert("common");
|
ReservedSet->insert("common");
|
||||||
|
@ -756,7 +778,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
||||||
loc = ppToken.loc;
|
loc = ppToken.loc;
|
||||||
parserToken->sType.lex.loc = loc;
|
parserToken->sType.lex.loc = loc;
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case ';': afterType = false; return SEMICOLON;
|
case ';': afterType = false; afterBuffer = false; return SEMICOLON;
|
||||||
case ',': afterType = false; return COMMA;
|
case ',': afterType = false; return COMMA;
|
||||||
case ':': return COLON;
|
case ':': return COLON;
|
||||||
case '=': afterType = false; return EQUAL;
|
case '=': afterType = false; return EQUAL;
|
||||||
|
@ -778,7 +800,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
||||||
case '?': return QUESTION;
|
case '?': return QUESTION;
|
||||||
case '[': return LEFT_BRACKET;
|
case '[': return LEFT_BRACKET;
|
||||||
case ']': return RIGHT_BRACKET;
|
case ']': return RIGHT_BRACKET;
|
||||||
case '{': afterStruct = false; return LEFT_BRACE;
|
case '{': afterStruct = false; afterBuffer = false; return LEFT_BRACE;
|
||||||
case '}': return RIGHT_BRACE;
|
case '}': return RIGHT_BRACE;
|
||||||
case '\\':
|
case '\\':
|
||||||
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
||||||
|
@ -925,11 +947,26 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
case BUFFER:
|
case BUFFER:
|
||||||
|
afterBuffer = true;
|
||||||
if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
|
if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
|
||||||
(parseContext.profile != EEsProfile && parseContext.version < 430))
|
(parseContext.profile != EEsProfile && parseContext.version < 430))
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case PAYLOADNV:
|
||||||
|
case PAYLOADINNV:
|
||||||
|
case HITATTRNV:
|
||||||
|
case CALLDATANV:
|
||||||
|
case CALLDATAINNV:
|
||||||
|
case ACCSTRUCTNV:
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
(parseContext.profile != EEsProfile && parseContext.version >= 460
|
||||||
|
&& parseContext.extensionTurnedOn(E_GL_NV_ray_tracing)))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
#endif
|
||||||
|
|
||||||
case ATOMIC_UINT:
|
case ATOMIC_UINT:
|
||||||
if ((parseContext.profile == EEsProfile && parseContext.version >= 310) ||
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 310) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters))
|
parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters))
|
||||||
|
@ -937,6 +974,11 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return es30ReservedFromGLSL(420);
|
return es30ReservedFromGLSL(420);
|
||||||
|
|
||||||
case COHERENT:
|
case COHERENT:
|
||||||
|
case DEVICECOHERENT:
|
||||||
|
case QUEUEFAMILYCOHERENT:
|
||||||
|
case WORKGROUPCOHERENT:
|
||||||
|
case SUBGROUPCOHERENT:
|
||||||
|
case NONPRIVATE:
|
||||||
case RESTRICT:
|
case RESTRICT:
|
||||||
case READONLY:
|
case READONLY:
|
||||||
case WRITEONLY:
|
case WRITEONLY:
|
||||||
|
@ -1094,8 +1136,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
(parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
(parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
||||||
(parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) ||
|
(parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int64))))
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64))))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
|
||||||
|
@ -1109,9 +1151,9 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case U8VEC4:
|
case U8VEC4:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) ||
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int8)) &&
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8)) &&
|
||||||
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
@ -1132,8 +1174,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
|
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
|
||||||
#endif
|
#endif
|
||||||
parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int16))))
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16))))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
case INT32_T:
|
case INT32_T:
|
||||||
|
@ -1146,8 +1188,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case U32VEC4:
|
case U32VEC4:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int32)) &&
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32)) &&
|
||||||
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
@ -1169,8 +1211,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case F32MAT4X4:
|
case F32MAT4X4:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float32)) &&
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) &&
|
||||||
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
@ -1193,8 +1235,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case F64MAT4X4:
|
case F64MAT4X4:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float64)) &&
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) &&
|
||||||
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
@ -1211,8 +1253,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
|
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
|
||||||
#endif
|
#endif
|
||||||
parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16))))
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))))
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
@ -1236,8 +1278,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
|
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
|
||||||
#endif
|
#endif
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16))))
|
parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))))
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
@ -1370,6 +1412,13 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
|
||||||
|
case SAMPLEREXTERNAL2DY2YEXT:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_EXT_YUV_target))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
case TEXTURE2D:
|
case TEXTURE2D:
|
||||||
case TEXTURECUBE:
|
case TEXTURECUBE:
|
||||||
case TEXTURECUBEARRAY:
|
case TEXTURECUBEARRAY:
|
||||||
|
@ -1490,13 +1539,22 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case __EXPLICITINTERPAMD:
|
case EXPLICITINTERPAMD:
|
||||||
if (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
if (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
||||||
parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter))
|
parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case PERVERTEXNV:
|
||||||
|
if (((parseContext.profile != EEsProfile && parseContext.version >= 450) ||
|
||||||
|
(parseContext.profile == EEsProfile && parseContext.version >= 320)) &&
|
||||||
|
parseContext.extensionTurnedOn(E_GL_NV_fragment_shader_barycentric))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
#endif
|
||||||
|
|
||||||
case FLAT:
|
case FLAT:
|
||||||
if (parseContext.profile == EEsProfile && parseContext.version < 300)
|
if (parseContext.profile == EEsProfile && parseContext.version < 300)
|
||||||
reservedWord();
|
reservedWord();
|
||||||
|
@ -1543,6 +1601,17 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return identifierOrReserved(reserved);
|
return identifierOrReserved(reserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case PERPRIMITIVENV:
|
||||||
|
case PERVIEWNV:
|
||||||
|
case PERTASKNV:
|
||||||
|
if ((parseContext.profile != EEsProfile && parseContext.version >= 450) ||
|
||||||
|
(parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_NV_mesh_shader))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
|
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1558,7 +1627,9 @@ int TScanContext::identifierOrType()
|
||||||
parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
|
parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
|
||||||
if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
|
if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
|
||||||
if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
|
if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
|
||||||
if (variable->isUserType()) {
|
if (variable->isUserType() &&
|
||||||
|
// treat redeclaration of forward-declared buffer/uniform reference as an identifier
|
||||||
|
!(variable->getType().getBasicType() == EbtReference && afterBuffer)) {
|
||||||
afterType = true;
|
afterType = true;
|
||||||
|
|
||||||
return TYPE_NAME;
|
return TYPE_NAME;
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
}
|
}
|
||||||
if (names != nullptr) {
|
if (names != nullptr) {
|
||||||
for (int i = 0; i < numSources; ++i)
|
for (int i = 0; i < numSources; ++i)
|
||||||
loc[i].name = names[i];
|
loc[i].name = names[i] != nullptr ? NewPoolTString(names[i]) : nullptr;
|
||||||
}
|
}
|
||||||
loc[currentSource].line = 1;
|
loc[currentSource].line = 1;
|
||||||
logicalSourceLoc.init(1);
|
logicalSourceLoc.init(1);
|
||||||
|
@ -170,16 +170,18 @@ public:
|
||||||
// for #line override in filename based parsing
|
// for #line override in filename based parsing
|
||||||
void setFile(const char* filename)
|
void setFile(const char* filename)
|
||||||
{
|
{
|
||||||
logicalSourceLoc.name = filename;
|
TString* fn_tstr = NewPoolTString(filename);
|
||||||
loc[getLastValidSourceIndex()].name = filename;
|
logicalSourceLoc.name = fn_tstr;
|
||||||
|
loc[getLastValidSourceIndex()].name = fn_tstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFile(const char* filename, int i)
|
void setFile(const char* filename, int i)
|
||||||
{
|
{
|
||||||
|
TString* fn_tstr = NewPoolTString(filename);
|
||||||
if (i == getLastValidSourceIndex()) {
|
if (i == getLastValidSourceIndex()) {
|
||||||
logicalSourceLoc.name = filename;
|
logicalSourceLoc.name = fn_tstr;
|
||||||
}
|
}
|
||||||
loc[i].name = filename;
|
loc[i].name = fn_tstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setString(int newString)
|
void setString(int newString)
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
explicit TScanContext(TParseContextBase& pc) :
|
explicit TScanContext(TParseContextBase& pc) :
|
||||||
parseContext(pc),
|
parseContext(pc),
|
||||||
afterType(false), afterStruct(false),
|
afterType(false), afterStruct(false),
|
||||||
field(false) { }
|
field(false), afterBuffer(false) { }
|
||||||
virtual ~TScanContext() { }
|
virtual ~TScanContext() { }
|
||||||
|
|
||||||
static void fillInKeywordMap();
|
static void fillInKeywordMap();
|
||||||
|
@ -81,6 +81,7 @@ protected:
|
||||||
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
|
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
|
||||||
bool afterStruct; // true if we've recognized the STRUCT keyword, so can only be looking for an identifier
|
bool afterStruct; // true if we've recognized the STRUCT keyword, so can only be looking for an identifier
|
||||||
bool field; // true if we're on a field, right after a '.'
|
bool field; // true if we're on a field, right after a '.'
|
||||||
|
bool afterBuffer; // true if we've recognized the BUFFER keyword
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
TParserToken* parserToken;
|
TParserToken* parserToken;
|
||||||
TPpToken* ppToken;
|
TPpToken* ppToken;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013-2016 LunarG, Inc.
|
// Copyright (C) 2013-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2017 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -67,6 +67,11 @@
|
||||||
#include "iomapper.h"
|
#include "iomapper.h"
|
||||||
#include "Initialize.h"
|
#include "Initialize.h"
|
||||||
|
|
||||||
|
// TODO: this really shouldn't be here, it is only because of the trial addition
|
||||||
|
// of printing pre-processed tokens, which requires knowing the string literal
|
||||||
|
// token to print ", but none of that seems appropriate for this file.
|
||||||
|
#include "preprocessor/PpTokens.h"
|
||||||
|
|
||||||
namespace { // anonymous namespace for file-local functions and symbols
|
namespace { // anonymous namespace for file-local functions and symbols
|
||||||
|
|
||||||
// Total number of successful initializers of glslang: a refcount
|
// Total number of successful initializers of glslang: a refcount
|
||||||
|
@ -342,6 +347,36 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// check for ray tracing stages
|
||||||
|
if (profile != EEsProfile && version >= 450) {
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for mesh
|
||||||
|
if ((profile != EEsProfile && version >= 450) ||
|
||||||
|
(profile == EEsProfile && version >= 320))
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
|
||||||
|
// check for task
|
||||||
|
if ((profile != EEsProfile && version >= 450) ||
|
||||||
|
(profile == EEsProfile && version >= 320))
|
||||||
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
||||||
|
infoSink, commonTable, symbolTables);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,6 +600,28 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
||||||
version = profile == EEsProfile ? 310 : 420;
|
version = profile == EEsProfile ? 310 : 420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EShLangRayGenNV:
|
||||||
|
case EShLangIntersectNV:
|
||||||
|
case EShLangAnyHitNV:
|
||||||
|
case EShLangClosestHitNV:
|
||||||
|
case EShLangMissNV:
|
||||||
|
case EShLangCallableNV:
|
||||||
|
if (profile == EEsProfile || version < 460) {
|
||||||
|
correct = false;
|
||||||
|
infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above");
|
||||||
|
version = 460;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EShLangMeshNV:
|
||||||
|
case EShLangTaskNV:
|
||||||
|
if ((profile == EEsProfile && version < 320) ||
|
||||||
|
(profile != EEsProfile && version < 450)) {
|
||||||
|
correct = false;
|
||||||
|
infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above");
|
||||||
|
version = profile == EEsProfile ? 320 : 450;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -822,8 +879,11 @@ bool ProcessDeferred(
|
||||||
intermediate.setHlslOffsets();
|
intermediate.setHlslOffsets();
|
||||||
if (messages & EShMsgDebugInfo) {
|
if (messages & EShMsgDebugInfo) {
|
||||||
intermediate.setSourceFile(names[numPre]);
|
intermediate.setSourceFile(names[numPre]);
|
||||||
for (int s = 0; s < numStrings; ++s)
|
for (int s = 0; s < numStrings; ++s) {
|
||||||
intermediate.addSourceText(strings[numPre + s]);
|
// The string may not be null-terminated, so make sure we provide
|
||||||
|
// the length along with the string.
|
||||||
|
intermediate.addSourceText(strings[numPre + s], lengths[numPre + s]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
||||||
|
|
||||||
|
@ -965,6 +1025,8 @@ private:
|
||||||
// DoPreprocessing is a valid ProcessingContext template argument,
|
// DoPreprocessing is a valid ProcessingContext template argument,
|
||||||
// which only performs the preprocessing step of compilation.
|
// which only performs the preprocessing step of compilation.
|
||||||
// It places the result in the "string" argument to its constructor.
|
// It places the result in the "string" argument to its constructor.
|
||||||
|
//
|
||||||
|
// This is not an officially supported or fully working path.
|
||||||
struct DoPreprocessing {
|
struct DoPreprocessing {
|
||||||
explicit DoPreprocessing(std::string* string): outputString(string) {}
|
explicit DoPreprocessing(std::string* string): outputString(string) {}
|
||||||
bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
|
bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
|
||||||
|
@ -1072,7 +1134,11 @@ struct DoPreprocessing {
|
||||||
outputBuffer += ' ';
|
outputBuffer += ' ';
|
||||||
}
|
}
|
||||||
lastToken = token;
|
lastToken = token;
|
||||||
|
if (token == PpAtomConstString)
|
||||||
|
outputBuffer += "\"";
|
||||||
outputBuffer += ppToken.name;
|
outputBuffer += ppToken.name;
|
||||||
|
if (token == PpAtomConstString)
|
||||||
|
outputBuffer += "\"";
|
||||||
} while (true);
|
} while (true);
|
||||||
outputBuffer += '\n';
|
outputBuffer += '\n';
|
||||||
*outputString = std::move(outputBuffer);
|
*outputString = std::move(outputBuffer);
|
||||||
|
@ -1122,6 +1188,9 @@ struct DoFullParse{
|
||||||
// Return: True if there were no issues found in preprocessing,
|
// Return: True if there were no issues found in preprocessing,
|
||||||
// False if during preprocessing any unknown version, pragmas or
|
// False if during preprocessing any unknown version, pragmas or
|
||||||
// extensions were found.
|
// extensions were found.
|
||||||
|
//
|
||||||
|
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
|
||||||
|
// is not an officially supported or fully working path.
|
||||||
bool PreprocessDeferred(
|
bool PreprocessDeferred(
|
||||||
TCompiler* compiler,
|
TCompiler* compiler,
|
||||||
const char* const shaderStrings[],
|
const char* const shaderStrings[],
|
||||||
|
@ -1266,7 +1335,7 @@ void ShDestruct(ShHandle handle)
|
||||||
//
|
//
|
||||||
// Cleanup symbol tables
|
// Cleanup symbol tables
|
||||||
//
|
//
|
||||||
int __fastcall ShFinalize()
|
int ShFinalize()
|
||||||
{
|
{
|
||||||
glslang::GetGlobalLock();
|
glslang::GetGlobalLock();
|
||||||
--NumberOfClients;
|
--NumberOfClients;
|
||||||
|
@ -1695,6 +1764,14 @@ void TShader::setAutoMapBindings(bool map) { intermediate->setAutoM
|
||||||
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
|
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
|
||||||
// Fragile: currently within one stage: simple auto-assignment of location
|
// Fragile: currently within one stage: simple auto-assignment of location
|
||||||
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
||||||
|
void TShader::addUniformLocationOverride(const char* name, int loc)
|
||||||
|
{
|
||||||
|
intermediate->addUniformLocationOverride(name, loc);
|
||||||
|
}
|
||||||
|
void TShader::setUniformLocationBase(int base)
|
||||||
|
{
|
||||||
|
intermediate->setUniformLocationBase(base);
|
||||||
|
}
|
||||||
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
|
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
|
||||||
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
|
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
|
||||||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||||
|
@ -1726,6 +1803,9 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
||||||
|
|
||||||
// Fill in a string with the result of preprocessing ShaderStrings
|
// Fill in a string with the result of preprocessing ShaderStrings
|
||||||
// Returns true if all extensions, pragmas and version strings were valid.
|
// Returns true if all extensions, pragmas and version strings were valid.
|
||||||
|
//
|
||||||
|
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
|
||||||
|
// is not an officially supported or fully working path.
|
||||||
bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
||||||
int defaultVersion, EProfile defaultProfile,
|
int defaultVersion, EProfile defaultProfile,
|
||||||
bool forceDefaultVersionAndProfile,
|
bool forceDefaultVersionAndProfile,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -72,6 +73,9 @@ void TType::buildMangledName(TString& mangledName) const
|
||||||
case EbtUint64: mangledName += "u64"; break;
|
case EbtUint64: mangledName += "u64"; break;
|
||||||
case EbtBool: mangledName += 'b'; break;
|
case EbtBool: mangledName += 'b'; break;
|
||||||
case EbtAtomicUint: mangledName += "au"; break;
|
case EbtAtomicUint: mangledName += "au"; break;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EbtAccStructNV: mangledName += "asnv"; break;
|
||||||
|
#endif
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
switch (sampler.type) {
|
switch (sampler.type) {
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
|
@ -95,6 +99,8 @@ void TType::buildMangledName(TString& mangledName) const
|
||||||
mangledName += "S";
|
mangledName += "S";
|
||||||
if (sampler.external)
|
if (sampler.external)
|
||||||
mangledName += "E";
|
mangledName += "E";
|
||||||
|
if (sampler.yuv)
|
||||||
|
mangledName += "Y";
|
||||||
switch (sampler.dim) {
|
switch (sampler.dim) {
|
||||||
case Esd1D: mangledName += "1"; break;
|
case Esd1D: mangledName += "1"; break;
|
||||||
case Esd2D: mangledName += "2"; break;
|
case Esd2D: mangledName += "2"; break;
|
||||||
|
@ -283,19 +289,25 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
|
||||||
{
|
{
|
||||||
type.deepCopy(copyOf.type);
|
type.deepCopy(copyOf.type);
|
||||||
userType = copyOf.userType;
|
userType = copyOf.userType;
|
||||||
numExtensions = 0;
|
|
||||||
extensions = 0;
|
// we don't support specialization-constant subtrees in cloned tables, only extensions
|
||||||
if (copyOf.numExtensions != 0)
|
constSubtree = nullptr;
|
||||||
setExtensions(copyOf.numExtensions, copyOf.extensions);
|
extensions = nullptr;
|
||||||
|
memberExtensions = nullptr;
|
||||||
|
if (copyOf.getNumExtensions() > 0)
|
||||||
|
setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions());
|
||||||
|
if (copyOf.hasMemberExtensions()) {
|
||||||
|
for (int m = 0; m < (int)copyOf.type.getStruct()->size(); ++m) {
|
||||||
|
if (copyOf.getNumMemberExtensions(m) > 0)
|
||||||
|
setMemberExtensions(m, copyOf.getNumMemberExtensions(m), copyOf.getMemberExtensions(m));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (! copyOf.constArray.empty()) {
|
if (! copyOf.constArray.empty()) {
|
||||||
assert(! copyOf.type.isStruct());
|
assert(! copyOf.type.isStruct());
|
||||||
TConstUnionArray newArray(copyOf.constArray, 0, copyOf.constArray.size());
|
TConstUnionArray newArray(copyOf.constArray, 0, copyOf.constArray.size());
|
||||||
constArray = newArray;
|
constArray = newArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't support specialization-constant subtrees in cloned tables
|
|
||||||
constSubtree = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TVariable* TVariable::clone() const
|
TVariable* TVariable::clone() const
|
||||||
|
@ -313,10 +325,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
|
||||||
parameters.back().copyParam(copyOf.parameters[i]);
|
parameters.back().copyParam(copyOf.parameters[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
numExtensions = 0;
|
extensions = nullptr;
|
||||||
extensions = 0;
|
if (copyOf.getNumExtensions() > 0)
|
||||||
if (copyOf.extensions != 0)
|
setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions());
|
||||||
setExtensions(copyOf.numExtensions, copyOf.extensions);
|
|
||||||
returnType.deepCopy(copyOf.returnType);
|
returnType.deepCopy(copyOf.returnType);
|
||||||
mangledName = copyOf.mangledName;
|
mangledName = copyOf.mangledName;
|
||||||
op = copyOf.op;
|
op = copyOf.op;
|
||||||
|
@ -355,12 +366,12 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
||||||
const TAnonMember* anon = iter->second->getAsAnonMember();
|
const TAnonMember* anon = iter->second->getAsAnonMember();
|
||||||
if (anon) {
|
if (anon) {
|
||||||
// Insert all the anonymous members of this same container at once,
|
// Insert all the anonymous members of this same container at once,
|
||||||
// avoid inserting the other members in the future, once this has been done,
|
// avoid inserting the remaining members in the future, once this has been done,
|
||||||
// allowing them to all be part of the same new container.
|
// allowing them to all be part of the same new container.
|
||||||
if (! containerCopied[anon->getAnonId()]) {
|
if (! containerCopied[anon->getAnonId()]) {
|
||||||
TVariable* container = anon->getAnonContainer().clone();
|
TVariable* container = anon->getAnonContainer().clone();
|
||||||
container->changeName(NewPoolTString(""));
|
container->changeName(NewPoolTString(""));
|
||||||
// insert the whole container
|
// insert the container and all its members
|
||||||
symTableLevel->insert(*container, false);
|
symTableLevel->insert(*container, false);
|
||||||
containerCopied[anon->getAnonId()] = true;
|
containerCopied[anon->getAnonId()] = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -78,10 +79,12 @@ class TVariable;
|
||||||
class TFunction;
|
class TFunction;
|
||||||
class TAnonMember;
|
class TAnonMember;
|
||||||
|
|
||||||
|
typedef TVector<const char*> TExtensionList;
|
||||||
|
|
||||||
class TSymbol {
|
class TSymbol {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
explicit TSymbol(const TString *n) : name(n), numExtensions(0), extensions(0), writable(true) { }
|
explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { }
|
||||||
virtual TSymbol* clone() const = 0;
|
virtual TSymbol* clone() const = 0;
|
||||||
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
|
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
|
||||||
|
|
||||||
|
@ -103,17 +106,16 @@ public:
|
||||||
virtual TType& getWritableType() = 0;
|
virtual TType& getWritableType() = 0;
|
||||||
virtual void setUniqueId(int id) { uniqueId = id; }
|
virtual void setUniqueId(int id) { uniqueId = id; }
|
||||||
virtual int getUniqueId() const { return uniqueId; }
|
virtual int getUniqueId() const { return uniqueId; }
|
||||||
virtual void setExtensions(int num, const char* const exts[])
|
virtual void setExtensions(int numExts, const char* const exts[])
|
||||||
{
|
{
|
||||||
assert(extensions == 0);
|
assert(extensions == 0);
|
||||||
assert(num > 0);
|
assert(numExts > 0);
|
||||||
numExtensions = num;
|
extensions = NewPoolObject(extensions);
|
||||||
extensions = NewPoolObject(exts[0], num);
|
for (int e = 0; e < numExts; ++e)
|
||||||
for (int e = 0; e < num; ++e)
|
extensions->push_back(exts[e]);
|
||||||
extensions[e] = exts[e];
|
|
||||||
}
|
}
|
||||||
virtual int getNumExtensions() const { return numExtensions; }
|
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
||||||
virtual const char** getExtensions() const { return extensions; }
|
virtual const char** getExtensions() const { return extensions->data(); }
|
||||||
virtual void dump(TInfoSink &infoSink) const = 0;
|
virtual void dump(TInfoSink &infoSink) const = 0;
|
||||||
|
|
||||||
virtual bool isReadOnly() const { return ! writable; }
|
virtual bool isReadOnly() const { return ! writable; }
|
||||||
|
@ -128,8 +130,7 @@ protected:
|
||||||
|
|
||||||
// For tracking what extensions must be present
|
// For tracking what extensions must be present
|
||||||
// (don't use if correct version/profile is present).
|
// (don't use if correct version/profile is present).
|
||||||
int numExtensions;
|
TExtensionList* extensions; // an array of pointers to existing constant char strings
|
||||||
const char** extensions; // an array of pointers to existing constant char strings
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// N.B.: Non-const functions that will be generally used should assert on this,
|
// N.B.: Non-const functions that will be generally used should assert on this,
|
||||||
|
@ -154,7 +155,9 @@ public:
|
||||||
: TSymbol(name),
|
: TSymbol(name),
|
||||||
userType(uT),
|
userType(uT),
|
||||||
constSubtree(nullptr),
|
constSubtree(nullptr),
|
||||||
anonId(-1) { type.shallowCopy(t); }
|
memberExtensions(nullptr),
|
||||||
|
anonId(-1)
|
||||||
|
{ type.shallowCopy(t); }
|
||||||
virtual TVariable* clone() const;
|
virtual TVariable* clone() const;
|
||||||
virtual ~TVariable() { }
|
virtual ~TVariable() { }
|
||||||
|
|
||||||
|
@ -171,6 +174,24 @@ public:
|
||||||
virtual void setAnonId(int i) { anonId = i; }
|
virtual void setAnonId(int i) { anonId = i; }
|
||||||
virtual int getAnonId() const { return anonId; }
|
virtual int getAnonId() const { return anonId; }
|
||||||
|
|
||||||
|
virtual void setMemberExtensions(int member, int numExts, const char* const exts[])
|
||||||
|
{
|
||||||
|
assert(type.isStruct());
|
||||||
|
assert(numExts > 0);
|
||||||
|
if (memberExtensions == nullptr) {
|
||||||
|
memberExtensions = NewPoolObject(memberExtensions);
|
||||||
|
memberExtensions->resize(type.getStruct()->size());
|
||||||
|
}
|
||||||
|
for (int e = 0; e < numExts; ++e)
|
||||||
|
(*memberExtensions)[member].push_back(exts[e]);
|
||||||
|
}
|
||||||
|
virtual bool hasMemberExtensions() const { return memberExtensions != nullptr; }
|
||||||
|
virtual int getNumMemberExtensions(int member) const
|
||||||
|
{
|
||||||
|
return memberExtensions == nullptr ? 0 : (int)(*memberExtensions)[member].size();
|
||||||
|
}
|
||||||
|
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
|
||||||
|
|
||||||
virtual void dump(TInfoSink &infoSink) const;
|
virtual void dump(TInfoSink &infoSink) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -179,15 +200,14 @@ protected:
|
||||||
|
|
||||||
TType type;
|
TType type;
|
||||||
bool userType;
|
bool userType;
|
||||||
|
|
||||||
// we are assuming that Pool Allocator will free the memory allocated to unionArray
|
// we are assuming that Pool Allocator will free the memory allocated to unionArray
|
||||||
// when this object is destroyed
|
// when this object is destroyed
|
||||||
|
|
||||||
// TODO: these two should be a union
|
TConstUnionArray constArray; // for compile-time constant value
|
||||||
// A variable could be a compile-time constant, or a specialization
|
TIntermTyped* constSubtree; // for specialization constant computation
|
||||||
// constant, or neither, but never both.
|
TVector<TExtensionList>* memberExtensions; // per-member extension list, allocated only when needed
|
||||||
TConstUnionArray constArray; // for compile-time constant value
|
int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
|
||||||
TIntermTyped* constSubtree; // for specialization constant computation
|
|
||||||
int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -324,35 +344,42 @@ protected:
|
||||||
//
|
//
|
||||||
class TAnonMember : public TSymbol {
|
class TAnonMember : public TSymbol {
|
||||||
public:
|
public:
|
||||||
TAnonMember(const TString* n, unsigned int m, const TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
|
TAnonMember(const TString* n, unsigned int m, TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
|
||||||
virtual TAnonMember* clone() const;
|
virtual TAnonMember* clone() const override;
|
||||||
virtual ~TAnonMember() { }
|
virtual ~TAnonMember() { }
|
||||||
|
|
||||||
virtual const TAnonMember* getAsAnonMember() const { return this; }
|
virtual const TAnonMember* getAsAnonMember() const override { return this; }
|
||||||
virtual const TVariable& getAnonContainer() const { return anonContainer; }
|
virtual const TVariable& getAnonContainer() const { return anonContainer; }
|
||||||
virtual unsigned int getMemberNumber() const { return memberNumber; }
|
virtual unsigned int getMemberNumber() const { return memberNumber; }
|
||||||
|
|
||||||
virtual const TType& getType() const
|
virtual const TType& getType() const override
|
||||||
{
|
{
|
||||||
const TTypeList& types = *anonContainer.getType().getStruct();
|
const TTypeList& types = *anonContainer.getType().getStruct();
|
||||||
return *types[memberNumber].type;
|
return *types[memberNumber].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TType& getWritableType()
|
virtual TType& getWritableType() override
|
||||||
{
|
{
|
||||||
assert(writable);
|
assert(writable);
|
||||||
const TTypeList& types = *anonContainer.getType().getStruct();
|
const TTypeList& types = *anonContainer.getType().getStruct();
|
||||||
return *types[memberNumber].type;
|
return *types[memberNumber].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void setExtensions(int numExts, const char* const exts[]) override
|
||||||
|
{
|
||||||
|
anonContainer.setMemberExtensions(memberNumber, numExts, exts);
|
||||||
|
}
|
||||||
|
virtual int getNumExtensions() const override { return anonContainer.getNumMemberExtensions(memberNumber); }
|
||||||
|
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
|
||||||
|
|
||||||
virtual int getAnonId() const { return anonId; }
|
virtual int getAnonId() const { return anonId; }
|
||||||
virtual void dump(TInfoSink &infoSink) const;
|
virtual void dump(TInfoSink &infoSink) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TAnonMember(const TAnonMember&);
|
explicit TAnonMember(const TAnonMember&);
|
||||||
TAnonMember& operator=(const TAnonMember&);
|
TAnonMember& operator=(const TAnonMember&);
|
||||||
|
|
||||||
const TVariable& anonContainer;
|
TVariable& anonContainer;
|
||||||
unsigned int memberNumber;
|
unsigned int memberNumber;
|
||||||
int anonId;
|
int anonId;
|
||||||
};
|
};
|
||||||
|
@ -788,11 +815,30 @@ public:
|
||||||
table[level]->setFunctionExtensions(name, num, extensions);
|
table[level]->setFunctionExtensions(name, num, extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVariableExtensions(const char* name, int num, const char* const extensions[])
|
void setVariableExtensions(const char* name, int numExts, const char* const extensions[])
|
||||||
{
|
{
|
||||||
TSymbol* symbol = find(TString(name));
|
TSymbol* symbol = find(TString(name));
|
||||||
if (symbol)
|
if (symbol == nullptr)
|
||||||
symbol->setExtensions(num, extensions);
|
return;
|
||||||
|
|
||||||
|
symbol->setExtensions(numExts, extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVariableExtensions(const char* blockName, const char* name, int numExts, const char* const extensions[])
|
||||||
|
{
|
||||||
|
TSymbol* symbol = find(TString(blockName));
|
||||||
|
if (symbol == nullptr)
|
||||||
|
return;
|
||||||
|
TVariable* variable = symbol->getAsVariable();
|
||||||
|
assert(variable != nullptr);
|
||||||
|
|
||||||
|
const TTypeList& structure = *variable->getAsVariable()->getType().getStruct();
|
||||||
|
for (int member = 0; member < (int)structure.size(); ++member) {
|
||||||
|
if (structure[member].type->getFieldName().compare(name) == 0) {
|
||||||
|
variable->setMemberExtensions(member, numExts, extensions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMaxSymbolId() { return uniqueId; }
|
int getMaxSymbolId() { return uniqueId; }
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -156,6 +157,7 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable;
|
extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_EGL_image_external] = EBhDisable;
|
extensionBehavior[E_GL_OES_EGL_image_external] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_EGL_image_external_essl3] = EBhDisable;
|
extensionBehavior[E_GL_OES_EGL_image_external_essl3] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_YUV_target] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shadow_samplers] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shadow_samplers] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable;
|
extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable;
|
||||||
|
@ -194,6 +196,9 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_clustered] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_clustered] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_quad] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_quad] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_memory_scope_semantics] = EBhDisable;
|
||||||
|
|
||||||
|
extensionBehavior[E_GL_EXT_shader_atomic_int64] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
|
||||||
|
@ -201,6 +206,9 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
|
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
|
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
|
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_buffer_reference] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
||||||
|
@ -232,6 +240,12 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_NV_conservative_raster_underestimation] = EBhDisable;
|
extensionBehavior[E_GL_NV_conservative_raster_underestimation] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_shader_noperspective_interpolation] = EBhDisable;
|
extensionBehavior[E_GL_NV_shader_noperspective_interpolation] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
|
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
|
@ -271,14 +285,14 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_OVR_multiview2] = EBhDisable;
|
extensionBehavior[E_GL_OVR_multiview2] = EBhDisable;
|
||||||
|
|
||||||
// explicit types
|
// explicit types
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int8] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int8] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int16] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int16] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int32] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int32] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int64] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int64] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float16] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float16] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float32] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float64] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float64] = EBhDisable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get code that is not part of a shared symbol table, is specific to this shader,
|
// Get code that is not part of a shared symbol table, is specific to this shader,
|
||||||
|
@ -294,6 +308,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_EXT_frag_depth 1\n"
|
"#define GL_EXT_frag_depth 1\n"
|
||||||
"#define GL_OES_EGL_image_external 1\n"
|
"#define GL_OES_EGL_image_external 1\n"
|
||||||
"#define GL_OES_EGL_image_external_essl3 1\n"
|
"#define GL_OES_EGL_image_external_essl3 1\n"
|
||||||
|
"#define GL_EXT_YUV_target 1\n"
|
||||||
"#define GL_EXT_shader_texture_lod 1\n"
|
"#define GL_EXT_shader_texture_lod 1\n"
|
||||||
"#define GL_EXT_shadow_samplers 1\n"
|
"#define GL_EXT_shadow_samplers 1\n"
|
||||||
|
|
||||||
|
@ -369,6 +384,9 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_EXT_shader_16bit_storage 1\n"
|
"#define GL_EXT_shader_16bit_storage 1\n"
|
||||||
"#define GL_EXT_shader_8bit_storage 1\n"
|
"#define GL_EXT_shader_8bit_storage 1\n"
|
||||||
"#define GL_EXT_samplerless_texture_functions 1\n"
|
"#define GL_EXT_samplerless_texture_functions 1\n"
|
||||||
|
"#define GL_EXT_scalar_block_layout 1\n"
|
||||||
|
"#define GL_EXT_fragment_invocation_density 1\n"
|
||||||
|
"#define GL_EXT_buffer_reference 1\n"
|
||||||
|
|
||||||
// GL_KHR_shader_subgroup
|
// GL_KHR_shader_subgroup
|
||||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
"#define GL_KHR_shader_subgroup_basic 1\n"
|
||||||
|
@ -380,6 +398,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_KHR_shader_subgroup_clustered 1\n"
|
"#define GL_KHR_shader_subgroup_clustered 1\n"
|
||||||
"#define GL_KHR_shader_subgroup_quad 1\n"
|
"#define GL_KHR_shader_subgroup_quad 1\n"
|
||||||
|
|
||||||
|
"#define E_GL_EXT_shader_atomic_int64 1\n"
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
"#define GL_AMD_shader_ballot 1\n"
|
"#define GL_AMD_shader_ballot 1\n"
|
||||||
"#define GL_AMD_shader_trinary_minmax 1\n"
|
"#define GL_AMD_shader_trinary_minmax 1\n"
|
||||||
|
@ -400,15 +420,21 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_NV_shader_atomic_int64 1\n"
|
"#define GL_NV_shader_atomic_int64 1\n"
|
||||||
"#define GL_NV_conservative_raster_underestimation 1\n"
|
"#define GL_NV_conservative_raster_underestimation 1\n"
|
||||||
"#define GL_NV_shader_subgroup_partitioned 1\n"
|
"#define GL_NV_shader_subgroup_partitioned 1\n"
|
||||||
|
"#define GL_NV_shading_rate_image 1\n"
|
||||||
|
"#define GL_NV_ray_tracing 1\n"
|
||||||
|
"#define GL_NV_fragment_shader_barycentric 1\n"
|
||||||
|
"#define GL_NV_compute_shader_derivatives 1\n"
|
||||||
|
"#define GL_NV_shader_texture_footprint 1\n"
|
||||||
|
"#define GL_NV_mesh_shader 1\n"
|
||||||
#endif
|
#endif
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types 1\n"
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types_int8 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types_int16 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_int16 1\n"
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types_int32 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_int32 1\n"
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types_int64 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_int64 1\n"
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types_float16 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_float16 1\n"
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types_float32 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_float32 1\n"
|
||||||
"#define GL_KHX_shader_explicit_arithmetic_types_float64 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_float64 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
if (version >= 150) {
|
if (version >= 150) {
|
||||||
|
@ -487,6 +513,16 @@ const char* StageName(EShLanguage stage)
|
||||||
case EShLangGeometry: return "geometry";
|
case EShLangGeometry: return "geometry";
|
||||||
case EShLangFragment: return "fragment";
|
case EShLangFragment: return "fragment";
|
||||||
case EShLangCompute: return "compute";
|
case EShLangCompute: return "compute";
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EShLangRayGenNV: return "ray-generation";
|
||||||
|
case EShLangIntersectNV: return "intersection";
|
||||||
|
case EShLangAnyHitNV: return "any-hit";
|
||||||
|
case EShLangClosestHitNV: return "closest-hit";
|
||||||
|
case EShLangMissNV: return "miss";
|
||||||
|
case EShLangCallableNV: return "callable";
|
||||||
|
case EShLangMeshNV: return "mesh";
|
||||||
|
case EShLangTaskNV: return "task";
|
||||||
|
#endif
|
||||||
default: return "unknown stage";
|
default: return "unknown stage";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -715,6 +751,9 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if extension is used with correct shader stage
|
||||||
|
checkExtensionStage(getCurrentLoc(), extension);
|
||||||
|
|
||||||
// update the requested extension
|
// update the requested extension
|
||||||
updateExtensionBehavior(extension, behavior);
|
updateExtensionBehavior(extension, behavior);
|
||||||
|
|
||||||
|
@ -807,6 +846,20 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if extension is used with correct shader stage.
|
||||||
|
void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension)
|
||||||
|
{
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// GL_NV_mesh_shader extension is only allowed in task/mesh shaders
|
||||||
|
if (strcmp(extension, "GL_NV_mesh_shader") == 0) {
|
||||||
|
requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask),
|
||||||
|
"#extension GL_NV_mesh_shader");
|
||||||
|
profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader");
|
||||||
|
profileRequires(loc, EEsProfile, 320, 0, "#extension GL_NV_mesh_shader");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Call for any operation needing full GLSL integer data-type support.
|
// Call for any operation needing full GLSL integer data-type support.
|
||||||
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
|
@ -829,8 +882,8 @@ void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool bu
|
||||||
#if AMD_EXTENSIONS
|
#if AMD_EXTENSIONS
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
#endif
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -841,8 +894,8 @@ bool TParseVersions::float16Arithmetic()
|
||||||
#if AMD_EXTENSIONS
|
#if AMD_EXTENSIONS
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
#endif
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,16 +905,16 @@ bool TParseVersions::int16Arithmetic()
|
||||||
#if AMD_EXTENSIONS
|
#if AMD_EXTENSIONS
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
#endif
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TParseVersions::int8Arithmetic()
|
bool TParseVersions::int8Arithmetic()
|
||||||
{
|
{
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int8};
|
E_GL_EXT_shader_explicit_arithmetic_types_int8};
|
||||||
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,8 +929,8 @@ void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char*
|
||||||
#if AMD_EXTENSIONS
|
#if AMD_EXTENSIONS
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
#endif
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,8 +945,8 @@ void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* o
|
||||||
#if AMD_EXTENSIONS
|
#if AMD_EXTENSIONS
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
#endif
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -905,8 +958,8 @@ void TParseVersions::requireInt8Arithmetic(const TSourceLoc& loc, const char* op
|
||||||
combined += featureDesc;
|
combined += featureDesc;
|
||||||
|
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int8};
|
E_GL_EXT_shader_explicit_arithmetic_types_int8};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,8 +971,8 @@ void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char*
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
#endif
|
||||||
E_GL_EXT_shader_16bit_storage,
|
E_GL_EXT_shader_16bit_storage,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -928,8 +981,8 @@ void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char*
|
||||||
void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (!builtIn) {
|
if (!builtIn) {
|
||||||
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_float32};
|
E_GL_EXT_shader_explicit_arithmetic_types_float32};
|
||||||
requireExtensions(loc, 2, extensions, op);
|
requireExtensions(loc, 2, extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,8 +991,8 @@ void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op,
|
||||||
void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (!builtIn) {
|
if (!builtIn) {
|
||||||
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_float64};
|
E_GL_EXT_shader_explicit_arithmetic_types_float64};
|
||||||
requireExtensions(loc, 2, extensions, op);
|
requireExtensions(loc, 2, extensions, op);
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
||||||
|
@ -950,8 +1003,8 @@ void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op,
|
||||||
void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int8};
|
E_GL_EXT_shader_explicit_arithmetic_types_int8};
|
||||||
requireExtensions(loc, 2, extensions, op);
|
requireExtensions(loc, 2, extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -976,8 +1029,8 @@ void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, b
|
||||||
#if AMD_EXTENSIONS
|
#if AMD_EXTENSIONS
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
#endif
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -990,8 +1043,8 @@ void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* o
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
#endif
|
||||||
E_GL_EXT_shader_16bit_storage,
|
E_GL_EXT_shader_16bit_storage,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1001,8 +1054,8 @@ void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
E_GL_EXT_shader_8bit_storage,
|
E_GL_EXT_shader_8bit_storage,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int8};
|
E_GL_EXT_shader_explicit_arithmetic_types_int8};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1011,8 +1064,8 @@ void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op
|
||||||
void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int32};
|
E_GL_EXT_shader_explicit_arithmetic_types_int32};
|
||||||
requireExtensions(loc, 2, extensions, op);
|
requireExtensions(loc, 2, extensions, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1022,8 +1075,8 @@ void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool buil
|
||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[3] = {E_GL_ARB_gpu_shader_int64,
|
const char* const extensions[3] = {E_GL_ARB_gpu_shader_int64,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int64};
|
E_GL_EXT_shader_explicit_arithmetic_types_int64};
|
||||||
requireExtensions(loc, 3, extensions, op);
|
requireExtensions(loc, 3, extensions, op);
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -73,7 +74,7 @@ inline const char* ProfileName(EProfile profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// What source rules, validation rules, target language, etc. are needed
|
// What source rules, validation rules, target language, etc. are needed or
|
||||||
// desired for SPIR-V?
|
// desired for SPIR-V?
|
||||||
//
|
//
|
||||||
// 0 means a target or rule set is not enabled (ignore rules from that entity).
|
// 0 means a target or rule set is not enabled (ignore rules from that entity).
|
||||||
|
@ -109,6 +110,7 @@ const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_deriv
|
||||||
const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth";
|
const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth";
|
||||||
const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
|
const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
|
||||||
const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3";
|
const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3";
|
||||||
|
const char* const E_GL_EXT_YUV_target = "GL_EXT_YUV_target";
|
||||||
const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod";
|
const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod";
|
||||||
const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers";
|
const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers";
|
||||||
|
|
||||||
|
@ -148,6 +150,9 @@ const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_sub
|
||||||
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
|
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
|
||||||
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
|
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
|
||||||
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
|
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
|
||||||
|
const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics";
|
||||||
|
|
||||||
|
const char* const E_GL_EXT_shader_atomic_int64 = "GL_EXT_shader_atomic_int64";
|
||||||
|
|
||||||
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
||||||
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
||||||
|
@ -163,6 +168,9 @@ const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth
|
||||||
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
||||||
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
|
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
|
||||||
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
|
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
|
||||||
|
const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout";
|
||||||
|
const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
|
||||||
|
const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference";
|
||||||
|
|
||||||
// Arrays of extensions for the above viewportEXTs duplications
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
|
@ -204,6 +212,12 @@ const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_
|
||||||
const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation";
|
const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation";
|
||||||
const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_noperspective_interpolation";
|
const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_noperspective_interpolation";
|
||||||
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
|
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
|
||||||
|
const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image";
|
||||||
|
const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing";
|
||||||
|
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
|
||||||
|
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
|
||||||
|
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
|
||||||
|
const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_shader";
|
||||||
|
|
||||||
// Arrays of extensions for the above viewportEXTs duplications
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
|
@ -240,14 +254,14 @@ const char* const E_GL_OES_texture_buffer = "GL_OES_textur
|
||||||
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
||||||
|
|
||||||
// KHX
|
// KHX
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types = "GL_KHX_shader_explicit_arithmetic_types";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types";
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int8 = "GL_KHX_shader_explicit_arithmetic_types_int8";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8";
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int16 = "GL_KHX_shader_explicit_arithmetic_types_int16";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16";
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int32 = "GL_KHX_shader_explicit_arithmetic_types_int32";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int32 = "GL_EXT_shader_explicit_arithmetic_types_int32";
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int64 = "GL_KHX_shader_explicit_arithmetic_types_int64";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int64 = "GL_EXT_shader_explicit_arithmetic_types_int64";
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types_float16 = "GL_KHX_shader_explicit_arithmetic_types_float16";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float16 = "GL_EXT_shader_explicit_arithmetic_types_float16";
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types_float32 = "GL_KHX_shader_explicit_arithmetic_types_float32";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32";
|
||||||
const char* const E_GL_KHX_shader_explicit_arithmetic_types_float64 = "GL_KHX_shader_explicit_arithmetic_types_float64";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64";
|
||||||
|
|
||||||
// Arrays of extensions for the above AEP duplications
|
// Arrays of extensions for the above AEP duplications
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -140,13 +141,13 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
||||||
%token <lex> U8VEC2 U8VEC3 U8VEC4
|
%token <lex> U8VEC2 U8VEC3 U8VEC4
|
||||||
%token <lex> VEC2 VEC3 VEC4
|
%token <lex> VEC2 VEC3 VEC4
|
||||||
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
|
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
|
||||||
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM
|
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV
|
||||||
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
|
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT SUBGROUPCOHERENT NONPRIVATE
|
||||||
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
|
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
|
||||||
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
|
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
|
||||||
%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
|
%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
|
||||||
%token <lex> F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4
|
%token <lex> F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4
|
||||||
%token <lex> NOPERSPECTIVE FLAT SMOOTH LAYOUT __EXPLICITINTERPAMD
|
%token <lex> NOPERSPECTIVE FLAT SMOOTH LAYOUT EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV
|
||||||
|
|
||||||
%token <lex> MAT2X2 MAT2X3 MAT2X4
|
%token <lex> MAT2X2 MAT2X3 MAT2X4
|
||||||
%token <lex> MAT3X2 MAT3X3 MAT3X4
|
%token <lex> MAT3X2 MAT3X3 MAT3X4
|
||||||
|
@ -164,6 +165,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
||||||
%token <lex> F64MAT3X2 F64MAT3X3 F64MAT3X4
|
%token <lex> F64MAT3X2 F64MAT3X3 F64MAT3X4
|
||||||
%token <lex> F64MAT4X2 F64MAT4X3 F64MAT4X4
|
%token <lex> F64MAT4X2 F64MAT4X3 F64MAT4X4
|
||||||
%token <lex> ATOMIC_UINT
|
%token <lex> ATOMIC_UINT
|
||||||
|
%token <lex> ACCSTRUCTNV
|
||||||
|
|
||||||
// combined image/sampler
|
// combined image/sampler
|
||||||
%token <lex> SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
|
%token <lex> SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
|
||||||
|
@ -178,6 +180,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
||||||
%token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
|
%token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
|
||||||
%token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
|
%token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
|
||||||
%token <lex> SAMPLEREXTERNALOES
|
%token <lex> SAMPLEREXTERNALOES
|
||||||
|
%token <lex> SAMPLEREXTERNAL2DY2YEXT
|
||||||
|
|
||||||
%token <lex> F16SAMPLER1D F16SAMPLER2D F16SAMPLER3D F16SAMPLER2DRECT F16SAMPLERCUBE
|
%token <lex> F16SAMPLER1D F16SAMPLER2D F16SAMPLER3D F16SAMPLER2DRECT F16SAMPLERCUBE
|
||||||
%token <lex> F16SAMPLER1DARRAY F16SAMPLER2DARRAY F16SAMPLERCUBEARRAY
|
%token <lex> F16SAMPLER1DARRAY F16SAMPLER2DARRAY F16SAMPLERCUBEARRAY
|
||||||
|
@ -1135,13 +1138,53 @@ interpolation_qualifier
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.nopersp = true;
|
$$.qualifier.nopersp = true;
|
||||||
}
|
}
|
||||||
| __EXPLICITINTERPAMD {
|
| EXPLICITINTERPAMD {
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
parseContext.globalCheck($1.loc, "__explicitInterpAMD");
|
parseContext.globalCheck($1.loc, "__explicitInterpAMD");
|
||||||
parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation");
|
parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation");
|
||||||
parseContext.profileRequires($1.loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation");
|
parseContext.profileRequires($1.loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation");
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.explicitInterp = true;
|
$$.qualifier.explicitInterp = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| PERVERTEXNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
parseContext.globalCheck($1.loc, "pervertexNV");
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric");
|
||||||
|
parseContext.profileRequires($1.loc, ECompatibilityProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric");
|
||||||
|
parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.pervertexNV = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| PERPRIMITIVENV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
|
parseContext.globalCheck($1.loc, "perprimitiveNV");
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV");
|
||||||
|
// Fragment shader stage doesn't check for extension. So we explicitly add below extension check.
|
||||||
|
if (parseContext.language == EShLangFragment)
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.perPrimitiveNV = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| PERVIEWNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
|
parseContext.globalCheck($1.loc, "perviewNV");
|
||||||
|
parseContext.requireStage($1.loc, EShLangMeshNV, "perviewNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.perViewNV = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| PERTASKNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
|
parseContext.globalCheck($1.loc, "taskNV");
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.perTaskNV = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -1305,11 +1348,64 @@ storage_qualifier
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.storage = EvqBuffer;
|
$$.qualifier.storage = EvqBuffer;
|
||||||
}
|
}
|
||||||
|
| HITATTRNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
parseContext.globalCheck($1.loc, "hitAttributeNV");
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangClosestHitNVMask
|
||||||
|
| EShLangAnyHitNVMask), "hitAttributeNV");
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.storage = EvqHitAttrNV;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| PAYLOADNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
parseContext.globalCheck($1.loc, "rayPayloadNV");
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask |
|
||||||
|
EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadNV");
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.storage = EvqPayloadNV;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| PAYLOADINNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
parseContext.globalCheck($1.loc, "rayPayloadInNV");
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitNVMask |
|
||||||
|
EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadInNV");
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.storage = EvqPayloadInNV;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| CALLDATANV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
parseContext.globalCheck($1.loc, "callableDataNV");
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask |
|
||||||
|
EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), "callableDataNV");
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.storage = EvqCallableDataNV;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
| CALLDATAINNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
parseContext.globalCheck($1.loc, "callableDataInNV");
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV");
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV");
|
||||||
|
$$.init($1.loc);
|
||||||
|
$$.qualifier.storage = EvqCallableDataInNV;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
| SHARED {
|
| SHARED {
|
||||||
parseContext.globalCheck($1.loc, "shared");
|
parseContext.globalCheck($1.loc, "shared");
|
||||||
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
|
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared");
|
parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared");
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared");
|
||||||
|
#else
|
||||||
parseContext.requireStage($1.loc, EShLangCompute, "shared");
|
parseContext.requireStage($1.loc, EShLangCompute, "shared");
|
||||||
|
#endif
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.storage = EvqShared;
|
$$.qualifier.storage = EvqShared;
|
||||||
}
|
}
|
||||||
|
@ -1317,6 +1413,31 @@ storage_qualifier
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.coherent = true;
|
$$.qualifier.coherent = true;
|
||||||
}
|
}
|
||||||
|
| DEVICECOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent");
|
||||||
|
$$.qualifier.devicecoherent = true;
|
||||||
|
}
|
||||||
|
| QUEUEFAMILYCOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent");
|
||||||
|
$$.qualifier.queuefamilycoherent = true;
|
||||||
|
}
|
||||||
|
| WORKGROUPCOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent");
|
||||||
|
$$.qualifier.workgroupcoherent = true;
|
||||||
|
}
|
||||||
|
| SUBGROUPCOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent");
|
||||||
|
$$.qualifier.subgroupcoherent = true;
|
||||||
|
}
|
||||||
|
| NONPRIVATE {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate");
|
||||||
|
$$.qualifier.nonprivate = true;
|
||||||
|
}
|
||||||
| VOLATILE {
|
| VOLATILE {
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.volatil = true;
|
$$.qualifier.volatil = true;
|
||||||
|
@ -2114,6 +2235,12 @@ type_specifier_nonarray
|
||||||
$$.basicType = EbtDouble;
|
$$.basicType = EbtDouble;
|
||||||
$$.setMatrix(4, 4);
|
$$.setMatrix(4, 4);
|
||||||
}
|
}
|
||||||
|
| ACCSTRUCTNV {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
|
$$.basicType = EbtAccStructNV;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
| ATOMIC_UINT {
|
| ATOMIC_UINT {
|
||||||
parseContext.vulkanRemoved($1.loc, "atomic counter types");
|
parseContext.vulkanRemoved($1.loc, "atomic counter types");
|
||||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
|
@ -2985,6 +3112,12 @@ type_specifier_nonarray
|
||||||
$$.sampler.set(EbtFloat, Esd2D);
|
$$.sampler.set(EbtFloat, Esd2D);
|
||||||
$$.sampler.external = true;
|
$$.sampler.external = true;
|
||||||
}
|
}
|
||||||
|
| SAMPLEREXTERNAL2DY2YEXT { // GL_EXT_YUV_target
|
||||||
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
|
$$.basicType = EbtSampler;
|
||||||
|
$$.sampler.set(EbtFloat, Esd2D);
|
||||||
|
$$.sampler.yuv = true;
|
||||||
|
}
|
||||||
| SUBPASSINPUT {
|
| SUBPASSINPUT {
|
||||||
parseContext.requireStage($1.loc, EShLangFragment, "subpass input");
|
parseContext.requireStage($1.loc, EShLangFragment, "subpass input");
|
||||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
||||||
/* A Bison parser, made by GNU Bison 3.0. */
|
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -125,323 +125,339 @@ extern int yydebug;
|
||||||
BUFFER = 335,
|
BUFFER = 335,
|
||||||
SHARED = 336,
|
SHARED = 336,
|
||||||
NONUNIFORM = 337,
|
NONUNIFORM = 337,
|
||||||
COHERENT = 338,
|
PAYLOADNV = 338,
|
||||||
VOLATILE = 339,
|
PAYLOADINNV = 339,
|
||||||
RESTRICT = 340,
|
HITATTRNV = 340,
|
||||||
READONLY = 341,
|
CALLDATANV = 341,
|
||||||
WRITEONLY = 342,
|
CALLDATAINNV = 342,
|
||||||
DVEC2 = 343,
|
COHERENT = 343,
|
||||||
DVEC3 = 344,
|
VOLATILE = 344,
|
||||||
DVEC4 = 345,
|
RESTRICT = 345,
|
||||||
DMAT2 = 346,
|
READONLY = 346,
|
||||||
DMAT3 = 347,
|
WRITEONLY = 347,
|
||||||
DMAT4 = 348,
|
DEVICECOHERENT = 348,
|
||||||
F16VEC2 = 349,
|
QUEUEFAMILYCOHERENT = 349,
|
||||||
F16VEC3 = 350,
|
WORKGROUPCOHERENT = 350,
|
||||||
F16VEC4 = 351,
|
SUBGROUPCOHERENT = 351,
|
||||||
F16MAT2 = 352,
|
NONPRIVATE = 352,
|
||||||
F16MAT3 = 353,
|
DVEC2 = 353,
|
||||||
F16MAT4 = 354,
|
DVEC3 = 354,
|
||||||
F32VEC2 = 355,
|
DVEC4 = 355,
|
||||||
F32VEC3 = 356,
|
DMAT2 = 356,
|
||||||
F32VEC4 = 357,
|
DMAT3 = 357,
|
||||||
F32MAT2 = 358,
|
DMAT4 = 358,
|
||||||
F32MAT3 = 359,
|
F16VEC2 = 359,
|
||||||
F32MAT4 = 360,
|
F16VEC3 = 360,
|
||||||
F64VEC2 = 361,
|
F16VEC4 = 361,
|
||||||
F64VEC3 = 362,
|
F16MAT2 = 362,
|
||||||
F64VEC4 = 363,
|
F16MAT3 = 363,
|
||||||
F64MAT2 = 364,
|
F16MAT4 = 364,
|
||||||
F64MAT3 = 365,
|
F32VEC2 = 365,
|
||||||
F64MAT4 = 366,
|
F32VEC3 = 366,
|
||||||
NOPERSPECTIVE = 367,
|
F32VEC4 = 367,
|
||||||
FLAT = 368,
|
F32MAT2 = 368,
|
||||||
SMOOTH = 369,
|
F32MAT3 = 369,
|
||||||
LAYOUT = 370,
|
F32MAT4 = 370,
|
||||||
__EXPLICITINTERPAMD = 371,
|
F64VEC2 = 371,
|
||||||
MAT2X2 = 372,
|
F64VEC3 = 372,
|
||||||
MAT2X3 = 373,
|
F64VEC4 = 373,
|
||||||
MAT2X4 = 374,
|
F64MAT2 = 374,
|
||||||
MAT3X2 = 375,
|
F64MAT3 = 375,
|
||||||
MAT3X3 = 376,
|
F64MAT4 = 376,
|
||||||
MAT3X4 = 377,
|
NOPERSPECTIVE = 377,
|
||||||
MAT4X2 = 378,
|
FLAT = 378,
|
||||||
MAT4X3 = 379,
|
SMOOTH = 379,
|
||||||
MAT4X4 = 380,
|
LAYOUT = 380,
|
||||||
DMAT2X2 = 381,
|
EXPLICITINTERPAMD = 381,
|
||||||
DMAT2X3 = 382,
|
PERVERTEXNV = 382,
|
||||||
DMAT2X4 = 383,
|
PERPRIMITIVENV = 383,
|
||||||
DMAT3X2 = 384,
|
PERVIEWNV = 384,
|
||||||
DMAT3X3 = 385,
|
PERTASKNV = 385,
|
||||||
DMAT3X4 = 386,
|
MAT2X2 = 386,
|
||||||
DMAT4X2 = 387,
|
MAT2X3 = 387,
|
||||||
DMAT4X3 = 388,
|
MAT2X4 = 388,
|
||||||
DMAT4X4 = 389,
|
MAT3X2 = 389,
|
||||||
F16MAT2X2 = 390,
|
MAT3X3 = 390,
|
||||||
F16MAT2X3 = 391,
|
MAT3X4 = 391,
|
||||||
F16MAT2X4 = 392,
|
MAT4X2 = 392,
|
||||||
F16MAT3X2 = 393,
|
MAT4X3 = 393,
|
||||||
F16MAT3X3 = 394,
|
MAT4X4 = 394,
|
||||||
F16MAT3X4 = 395,
|
DMAT2X2 = 395,
|
||||||
F16MAT4X2 = 396,
|
DMAT2X3 = 396,
|
||||||
F16MAT4X3 = 397,
|
DMAT2X4 = 397,
|
||||||
F16MAT4X4 = 398,
|
DMAT3X2 = 398,
|
||||||
F32MAT2X2 = 399,
|
DMAT3X3 = 399,
|
||||||
F32MAT2X3 = 400,
|
DMAT3X4 = 400,
|
||||||
F32MAT2X4 = 401,
|
DMAT4X2 = 401,
|
||||||
F32MAT3X2 = 402,
|
DMAT4X3 = 402,
|
||||||
F32MAT3X3 = 403,
|
DMAT4X4 = 403,
|
||||||
F32MAT3X4 = 404,
|
F16MAT2X2 = 404,
|
||||||
F32MAT4X2 = 405,
|
F16MAT2X3 = 405,
|
||||||
F32MAT4X3 = 406,
|
F16MAT2X4 = 406,
|
||||||
F32MAT4X4 = 407,
|
F16MAT3X2 = 407,
|
||||||
F64MAT2X2 = 408,
|
F16MAT3X3 = 408,
|
||||||
F64MAT2X3 = 409,
|
F16MAT3X4 = 409,
|
||||||
F64MAT2X4 = 410,
|
F16MAT4X2 = 410,
|
||||||
F64MAT3X2 = 411,
|
F16MAT4X3 = 411,
|
||||||
F64MAT3X3 = 412,
|
F16MAT4X4 = 412,
|
||||||
F64MAT3X4 = 413,
|
F32MAT2X2 = 413,
|
||||||
F64MAT4X2 = 414,
|
F32MAT2X3 = 414,
|
||||||
F64MAT4X3 = 415,
|
F32MAT2X4 = 415,
|
||||||
F64MAT4X4 = 416,
|
F32MAT3X2 = 416,
|
||||||
ATOMIC_UINT = 417,
|
F32MAT3X3 = 417,
|
||||||
SAMPLER1D = 418,
|
F32MAT3X4 = 418,
|
||||||
SAMPLER2D = 419,
|
F32MAT4X2 = 419,
|
||||||
SAMPLER3D = 420,
|
F32MAT4X3 = 420,
|
||||||
SAMPLERCUBE = 421,
|
F32MAT4X4 = 421,
|
||||||
SAMPLER1DSHADOW = 422,
|
F64MAT2X2 = 422,
|
||||||
SAMPLER2DSHADOW = 423,
|
F64MAT2X3 = 423,
|
||||||
SAMPLERCUBESHADOW = 424,
|
F64MAT2X4 = 424,
|
||||||
SAMPLER1DARRAY = 425,
|
F64MAT3X2 = 425,
|
||||||
SAMPLER2DARRAY = 426,
|
F64MAT3X3 = 426,
|
||||||
SAMPLER1DARRAYSHADOW = 427,
|
F64MAT3X4 = 427,
|
||||||
SAMPLER2DARRAYSHADOW = 428,
|
F64MAT4X2 = 428,
|
||||||
ISAMPLER1D = 429,
|
F64MAT4X3 = 429,
|
||||||
ISAMPLER2D = 430,
|
F64MAT4X4 = 430,
|
||||||
ISAMPLER3D = 431,
|
ATOMIC_UINT = 431,
|
||||||
ISAMPLERCUBE = 432,
|
ACCSTRUCTNV = 432,
|
||||||
ISAMPLER1DARRAY = 433,
|
SAMPLER1D = 433,
|
||||||
ISAMPLER2DARRAY = 434,
|
SAMPLER2D = 434,
|
||||||
USAMPLER1D = 435,
|
SAMPLER3D = 435,
|
||||||
USAMPLER2D = 436,
|
SAMPLERCUBE = 436,
|
||||||
USAMPLER3D = 437,
|
SAMPLER1DSHADOW = 437,
|
||||||
USAMPLERCUBE = 438,
|
SAMPLER2DSHADOW = 438,
|
||||||
USAMPLER1DARRAY = 439,
|
SAMPLERCUBESHADOW = 439,
|
||||||
USAMPLER2DARRAY = 440,
|
SAMPLER1DARRAY = 440,
|
||||||
SAMPLER2DRECT = 441,
|
SAMPLER2DARRAY = 441,
|
||||||
SAMPLER2DRECTSHADOW = 442,
|
SAMPLER1DARRAYSHADOW = 442,
|
||||||
ISAMPLER2DRECT = 443,
|
SAMPLER2DARRAYSHADOW = 443,
|
||||||
USAMPLER2DRECT = 444,
|
ISAMPLER1D = 444,
|
||||||
SAMPLERBUFFER = 445,
|
ISAMPLER2D = 445,
|
||||||
ISAMPLERBUFFER = 446,
|
ISAMPLER3D = 446,
|
||||||
USAMPLERBUFFER = 447,
|
ISAMPLERCUBE = 447,
|
||||||
SAMPLERCUBEARRAY = 448,
|
ISAMPLER1DARRAY = 448,
|
||||||
SAMPLERCUBEARRAYSHADOW = 449,
|
ISAMPLER2DARRAY = 449,
|
||||||
ISAMPLERCUBEARRAY = 450,
|
USAMPLER1D = 450,
|
||||||
USAMPLERCUBEARRAY = 451,
|
USAMPLER2D = 451,
|
||||||
SAMPLER2DMS = 452,
|
USAMPLER3D = 452,
|
||||||
ISAMPLER2DMS = 453,
|
USAMPLERCUBE = 453,
|
||||||
USAMPLER2DMS = 454,
|
USAMPLER1DARRAY = 454,
|
||||||
SAMPLER2DMSARRAY = 455,
|
USAMPLER2DARRAY = 455,
|
||||||
ISAMPLER2DMSARRAY = 456,
|
SAMPLER2DRECT = 456,
|
||||||
USAMPLER2DMSARRAY = 457,
|
SAMPLER2DRECTSHADOW = 457,
|
||||||
SAMPLEREXTERNALOES = 458,
|
ISAMPLER2DRECT = 458,
|
||||||
F16SAMPLER1D = 459,
|
USAMPLER2DRECT = 459,
|
||||||
F16SAMPLER2D = 460,
|
SAMPLERBUFFER = 460,
|
||||||
F16SAMPLER3D = 461,
|
ISAMPLERBUFFER = 461,
|
||||||
F16SAMPLER2DRECT = 462,
|
USAMPLERBUFFER = 462,
|
||||||
F16SAMPLERCUBE = 463,
|
SAMPLERCUBEARRAY = 463,
|
||||||
F16SAMPLER1DARRAY = 464,
|
SAMPLERCUBEARRAYSHADOW = 464,
|
||||||
F16SAMPLER2DARRAY = 465,
|
ISAMPLERCUBEARRAY = 465,
|
||||||
F16SAMPLERCUBEARRAY = 466,
|
USAMPLERCUBEARRAY = 466,
|
||||||
F16SAMPLERBUFFER = 467,
|
SAMPLER2DMS = 467,
|
||||||
F16SAMPLER2DMS = 468,
|
ISAMPLER2DMS = 468,
|
||||||
F16SAMPLER2DMSARRAY = 469,
|
USAMPLER2DMS = 469,
|
||||||
F16SAMPLER1DSHADOW = 470,
|
SAMPLER2DMSARRAY = 470,
|
||||||
F16SAMPLER2DSHADOW = 471,
|
ISAMPLER2DMSARRAY = 471,
|
||||||
F16SAMPLER1DARRAYSHADOW = 472,
|
USAMPLER2DMSARRAY = 472,
|
||||||
F16SAMPLER2DARRAYSHADOW = 473,
|
SAMPLEREXTERNALOES = 473,
|
||||||
F16SAMPLER2DRECTSHADOW = 474,
|
SAMPLEREXTERNAL2DY2YEXT = 474,
|
||||||
F16SAMPLERCUBESHADOW = 475,
|
F16SAMPLER1D = 475,
|
||||||
F16SAMPLERCUBEARRAYSHADOW = 476,
|
F16SAMPLER2D = 476,
|
||||||
SAMPLER = 477,
|
F16SAMPLER3D = 477,
|
||||||
SAMPLERSHADOW = 478,
|
F16SAMPLER2DRECT = 478,
|
||||||
TEXTURE1D = 479,
|
F16SAMPLERCUBE = 479,
|
||||||
TEXTURE2D = 480,
|
F16SAMPLER1DARRAY = 480,
|
||||||
TEXTURE3D = 481,
|
F16SAMPLER2DARRAY = 481,
|
||||||
TEXTURECUBE = 482,
|
F16SAMPLERCUBEARRAY = 482,
|
||||||
TEXTURE1DARRAY = 483,
|
F16SAMPLERBUFFER = 483,
|
||||||
TEXTURE2DARRAY = 484,
|
F16SAMPLER2DMS = 484,
|
||||||
ITEXTURE1D = 485,
|
F16SAMPLER2DMSARRAY = 485,
|
||||||
ITEXTURE2D = 486,
|
F16SAMPLER1DSHADOW = 486,
|
||||||
ITEXTURE3D = 487,
|
F16SAMPLER2DSHADOW = 487,
|
||||||
ITEXTURECUBE = 488,
|
F16SAMPLER1DARRAYSHADOW = 488,
|
||||||
ITEXTURE1DARRAY = 489,
|
F16SAMPLER2DARRAYSHADOW = 489,
|
||||||
ITEXTURE2DARRAY = 490,
|
F16SAMPLER2DRECTSHADOW = 490,
|
||||||
UTEXTURE1D = 491,
|
F16SAMPLERCUBESHADOW = 491,
|
||||||
UTEXTURE2D = 492,
|
F16SAMPLERCUBEARRAYSHADOW = 492,
|
||||||
UTEXTURE3D = 493,
|
SAMPLER = 493,
|
||||||
UTEXTURECUBE = 494,
|
SAMPLERSHADOW = 494,
|
||||||
UTEXTURE1DARRAY = 495,
|
TEXTURE1D = 495,
|
||||||
UTEXTURE2DARRAY = 496,
|
TEXTURE2D = 496,
|
||||||
TEXTURE2DRECT = 497,
|
TEXTURE3D = 497,
|
||||||
ITEXTURE2DRECT = 498,
|
TEXTURECUBE = 498,
|
||||||
UTEXTURE2DRECT = 499,
|
TEXTURE1DARRAY = 499,
|
||||||
TEXTUREBUFFER = 500,
|
TEXTURE2DARRAY = 500,
|
||||||
ITEXTUREBUFFER = 501,
|
ITEXTURE1D = 501,
|
||||||
UTEXTUREBUFFER = 502,
|
ITEXTURE2D = 502,
|
||||||
TEXTURECUBEARRAY = 503,
|
ITEXTURE3D = 503,
|
||||||
ITEXTURECUBEARRAY = 504,
|
ITEXTURECUBE = 504,
|
||||||
UTEXTURECUBEARRAY = 505,
|
ITEXTURE1DARRAY = 505,
|
||||||
TEXTURE2DMS = 506,
|
ITEXTURE2DARRAY = 506,
|
||||||
ITEXTURE2DMS = 507,
|
UTEXTURE1D = 507,
|
||||||
UTEXTURE2DMS = 508,
|
UTEXTURE2D = 508,
|
||||||
TEXTURE2DMSARRAY = 509,
|
UTEXTURE3D = 509,
|
||||||
ITEXTURE2DMSARRAY = 510,
|
UTEXTURECUBE = 510,
|
||||||
UTEXTURE2DMSARRAY = 511,
|
UTEXTURE1DARRAY = 511,
|
||||||
F16TEXTURE1D = 512,
|
UTEXTURE2DARRAY = 512,
|
||||||
F16TEXTURE2D = 513,
|
TEXTURE2DRECT = 513,
|
||||||
F16TEXTURE3D = 514,
|
ITEXTURE2DRECT = 514,
|
||||||
F16TEXTURE2DRECT = 515,
|
UTEXTURE2DRECT = 515,
|
||||||
F16TEXTURECUBE = 516,
|
TEXTUREBUFFER = 516,
|
||||||
F16TEXTURE1DARRAY = 517,
|
ITEXTUREBUFFER = 517,
|
||||||
F16TEXTURE2DARRAY = 518,
|
UTEXTUREBUFFER = 518,
|
||||||
F16TEXTURECUBEARRAY = 519,
|
TEXTURECUBEARRAY = 519,
|
||||||
F16TEXTUREBUFFER = 520,
|
ITEXTURECUBEARRAY = 520,
|
||||||
F16TEXTURE2DMS = 521,
|
UTEXTURECUBEARRAY = 521,
|
||||||
F16TEXTURE2DMSARRAY = 522,
|
TEXTURE2DMS = 522,
|
||||||
SUBPASSINPUT = 523,
|
ITEXTURE2DMS = 523,
|
||||||
SUBPASSINPUTMS = 524,
|
UTEXTURE2DMS = 524,
|
||||||
ISUBPASSINPUT = 525,
|
TEXTURE2DMSARRAY = 525,
|
||||||
ISUBPASSINPUTMS = 526,
|
ITEXTURE2DMSARRAY = 526,
|
||||||
USUBPASSINPUT = 527,
|
UTEXTURE2DMSARRAY = 527,
|
||||||
USUBPASSINPUTMS = 528,
|
F16TEXTURE1D = 528,
|
||||||
F16SUBPASSINPUT = 529,
|
F16TEXTURE2D = 529,
|
||||||
F16SUBPASSINPUTMS = 530,
|
F16TEXTURE3D = 530,
|
||||||
IMAGE1D = 531,
|
F16TEXTURE2DRECT = 531,
|
||||||
IIMAGE1D = 532,
|
F16TEXTURECUBE = 532,
|
||||||
UIMAGE1D = 533,
|
F16TEXTURE1DARRAY = 533,
|
||||||
IMAGE2D = 534,
|
F16TEXTURE2DARRAY = 534,
|
||||||
IIMAGE2D = 535,
|
F16TEXTURECUBEARRAY = 535,
|
||||||
UIMAGE2D = 536,
|
F16TEXTUREBUFFER = 536,
|
||||||
IMAGE3D = 537,
|
F16TEXTURE2DMS = 537,
|
||||||
IIMAGE3D = 538,
|
F16TEXTURE2DMSARRAY = 538,
|
||||||
UIMAGE3D = 539,
|
SUBPASSINPUT = 539,
|
||||||
IMAGE2DRECT = 540,
|
SUBPASSINPUTMS = 540,
|
||||||
IIMAGE2DRECT = 541,
|
ISUBPASSINPUT = 541,
|
||||||
UIMAGE2DRECT = 542,
|
ISUBPASSINPUTMS = 542,
|
||||||
IMAGECUBE = 543,
|
USUBPASSINPUT = 543,
|
||||||
IIMAGECUBE = 544,
|
USUBPASSINPUTMS = 544,
|
||||||
UIMAGECUBE = 545,
|
F16SUBPASSINPUT = 545,
|
||||||
IMAGEBUFFER = 546,
|
F16SUBPASSINPUTMS = 546,
|
||||||
IIMAGEBUFFER = 547,
|
IMAGE1D = 547,
|
||||||
UIMAGEBUFFER = 548,
|
IIMAGE1D = 548,
|
||||||
IMAGE1DARRAY = 549,
|
UIMAGE1D = 549,
|
||||||
IIMAGE1DARRAY = 550,
|
IMAGE2D = 550,
|
||||||
UIMAGE1DARRAY = 551,
|
IIMAGE2D = 551,
|
||||||
IMAGE2DARRAY = 552,
|
UIMAGE2D = 552,
|
||||||
IIMAGE2DARRAY = 553,
|
IMAGE3D = 553,
|
||||||
UIMAGE2DARRAY = 554,
|
IIMAGE3D = 554,
|
||||||
IMAGECUBEARRAY = 555,
|
UIMAGE3D = 555,
|
||||||
IIMAGECUBEARRAY = 556,
|
IMAGE2DRECT = 556,
|
||||||
UIMAGECUBEARRAY = 557,
|
IIMAGE2DRECT = 557,
|
||||||
IMAGE2DMS = 558,
|
UIMAGE2DRECT = 558,
|
||||||
IIMAGE2DMS = 559,
|
IMAGECUBE = 559,
|
||||||
UIMAGE2DMS = 560,
|
IIMAGECUBE = 560,
|
||||||
IMAGE2DMSARRAY = 561,
|
UIMAGECUBE = 561,
|
||||||
IIMAGE2DMSARRAY = 562,
|
IMAGEBUFFER = 562,
|
||||||
UIMAGE2DMSARRAY = 563,
|
IIMAGEBUFFER = 563,
|
||||||
F16IMAGE1D = 564,
|
UIMAGEBUFFER = 564,
|
||||||
F16IMAGE2D = 565,
|
IMAGE1DARRAY = 565,
|
||||||
F16IMAGE3D = 566,
|
IIMAGE1DARRAY = 566,
|
||||||
F16IMAGE2DRECT = 567,
|
UIMAGE1DARRAY = 567,
|
||||||
F16IMAGECUBE = 568,
|
IMAGE2DARRAY = 568,
|
||||||
F16IMAGE1DARRAY = 569,
|
IIMAGE2DARRAY = 569,
|
||||||
F16IMAGE2DARRAY = 570,
|
UIMAGE2DARRAY = 570,
|
||||||
F16IMAGECUBEARRAY = 571,
|
IMAGECUBEARRAY = 571,
|
||||||
F16IMAGEBUFFER = 572,
|
IIMAGECUBEARRAY = 572,
|
||||||
F16IMAGE2DMS = 573,
|
UIMAGECUBEARRAY = 573,
|
||||||
F16IMAGE2DMSARRAY = 574,
|
IMAGE2DMS = 574,
|
||||||
STRUCT = 575,
|
IIMAGE2DMS = 575,
|
||||||
VOID = 576,
|
UIMAGE2DMS = 576,
|
||||||
WHILE = 577,
|
IMAGE2DMSARRAY = 577,
|
||||||
IDENTIFIER = 578,
|
IIMAGE2DMSARRAY = 578,
|
||||||
TYPE_NAME = 579,
|
UIMAGE2DMSARRAY = 579,
|
||||||
FLOATCONSTANT = 580,
|
F16IMAGE1D = 580,
|
||||||
DOUBLECONSTANT = 581,
|
F16IMAGE2D = 581,
|
||||||
INT16CONSTANT = 582,
|
F16IMAGE3D = 582,
|
||||||
UINT16CONSTANT = 583,
|
F16IMAGE2DRECT = 583,
|
||||||
INT32CONSTANT = 584,
|
F16IMAGECUBE = 584,
|
||||||
UINT32CONSTANT = 585,
|
F16IMAGE1DARRAY = 585,
|
||||||
INTCONSTANT = 586,
|
F16IMAGE2DARRAY = 586,
|
||||||
UINTCONSTANT = 587,
|
F16IMAGECUBEARRAY = 587,
|
||||||
INT64CONSTANT = 588,
|
F16IMAGEBUFFER = 588,
|
||||||
UINT64CONSTANT = 589,
|
F16IMAGE2DMS = 589,
|
||||||
BOOLCONSTANT = 590,
|
F16IMAGE2DMSARRAY = 590,
|
||||||
FLOAT16CONSTANT = 591,
|
STRUCT = 591,
|
||||||
LEFT_OP = 592,
|
VOID = 592,
|
||||||
RIGHT_OP = 593,
|
WHILE = 593,
|
||||||
INC_OP = 594,
|
IDENTIFIER = 594,
|
||||||
DEC_OP = 595,
|
TYPE_NAME = 595,
|
||||||
LE_OP = 596,
|
FLOATCONSTANT = 596,
|
||||||
GE_OP = 597,
|
DOUBLECONSTANT = 597,
|
||||||
EQ_OP = 598,
|
INT16CONSTANT = 598,
|
||||||
NE_OP = 599,
|
UINT16CONSTANT = 599,
|
||||||
AND_OP = 600,
|
INT32CONSTANT = 600,
|
||||||
OR_OP = 601,
|
UINT32CONSTANT = 601,
|
||||||
XOR_OP = 602,
|
INTCONSTANT = 602,
|
||||||
MUL_ASSIGN = 603,
|
UINTCONSTANT = 603,
|
||||||
DIV_ASSIGN = 604,
|
INT64CONSTANT = 604,
|
||||||
ADD_ASSIGN = 605,
|
UINT64CONSTANT = 605,
|
||||||
MOD_ASSIGN = 606,
|
BOOLCONSTANT = 606,
|
||||||
LEFT_ASSIGN = 607,
|
FLOAT16CONSTANT = 607,
|
||||||
RIGHT_ASSIGN = 608,
|
LEFT_OP = 608,
|
||||||
AND_ASSIGN = 609,
|
RIGHT_OP = 609,
|
||||||
XOR_ASSIGN = 610,
|
INC_OP = 610,
|
||||||
OR_ASSIGN = 611,
|
DEC_OP = 611,
|
||||||
SUB_ASSIGN = 612,
|
LE_OP = 612,
|
||||||
LEFT_PAREN = 613,
|
GE_OP = 613,
|
||||||
RIGHT_PAREN = 614,
|
EQ_OP = 614,
|
||||||
LEFT_BRACKET = 615,
|
NE_OP = 615,
|
||||||
RIGHT_BRACKET = 616,
|
AND_OP = 616,
|
||||||
LEFT_BRACE = 617,
|
OR_OP = 617,
|
||||||
RIGHT_BRACE = 618,
|
XOR_OP = 618,
|
||||||
DOT = 619,
|
MUL_ASSIGN = 619,
|
||||||
COMMA = 620,
|
DIV_ASSIGN = 620,
|
||||||
COLON = 621,
|
ADD_ASSIGN = 621,
|
||||||
EQUAL = 622,
|
MOD_ASSIGN = 622,
|
||||||
SEMICOLON = 623,
|
LEFT_ASSIGN = 623,
|
||||||
BANG = 624,
|
RIGHT_ASSIGN = 624,
|
||||||
DASH = 625,
|
AND_ASSIGN = 625,
|
||||||
TILDE = 626,
|
XOR_ASSIGN = 626,
|
||||||
PLUS = 627,
|
OR_ASSIGN = 627,
|
||||||
STAR = 628,
|
SUB_ASSIGN = 628,
|
||||||
SLASH = 629,
|
LEFT_PAREN = 629,
|
||||||
PERCENT = 630,
|
RIGHT_PAREN = 630,
|
||||||
LEFT_ANGLE = 631,
|
LEFT_BRACKET = 631,
|
||||||
RIGHT_ANGLE = 632,
|
RIGHT_BRACKET = 632,
|
||||||
VERTICAL_BAR = 633,
|
LEFT_BRACE = 633,
|
||||||
CARET = 634,
|
RIGHT_BRACE = 634,
|
||||||
AMPERSAND = 635,
|
DOT = 635,
|
||||||
QUESTION = 636,
|
COMMA = 636,
|
||||||
INVARIANT = 637,
|
COLON = 637,
|
||||||
PRECISE = 638,
|
EQUAL = 638,
|
||||||
HIGH_PRECISION = 639,
|
SEMICOLON = 639,
|
||||||
MEDIUM_PRECISION = 640,
|
BANG = 640,
|
||||||
LOW_PRECISION = 641,
|
DASH = 641,
|
||||||
PRECISION = 642,
|
TILDE = 642,
|
||||||
PACKED = 643,
|
PLUS = 643,
|
||||||
RESOURCE = 644,
|
STAR = 644,
|
||||||
SUPERP = 645
|
SLASH = 645,
|
||||||
|
PERCENT = 646,
|
||||||
|
LEFT_ANGLE = 647,
|
||||||
|
RIGHT_ANGLE = 648,
|
||||||
|
VERTICAL_BAR = 649,
|
||||||
|
CARET = 650,
|
||||||
|
AMPERSAND = 651,
|
||||||
|
QUESTION = 652,
|
||||||
|
INVARIANT = 653,
|
||||||
|
PRECISE = 654,
|
||||||
|
HIGH_PRECISION = 655,
|
||||||
|
MEDIUM_PRECISION = 656,
|
||||||
|
LOW_PRECISION = 657,
|
||||||
|
PRECISION = 658,
|
||||||
|
PACKED = 659,
|
||||||
|
RESOURCE = 660,
|
||||||
|
SUPERP = 661
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Value type. */
|
/* Value type. */
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
typedef union YYSTYPE YYSTYPE;
|
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 70 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
#line 71 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
glslang::TSourceLoc loc;
|
glslang::TSourceLoc loc;
|
||||||
|
@ -476,8 +492,10 @@ union YYSTYPE
|
||||||
};
|
};
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
#line 480 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
#line 496 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef union YYSTYPE YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -172,8 +172,12 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||||
case EOpIndexDirect: out.debug << "direct index"; break;
|
case EOpIndexDirect: out.debug << "direct index"; break;
|
||||||
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
|
{
|
||||||
out.debug << ": direct index for structure"; break;
|
bool reference = node->getLeft()->getType().getBasicType() == EbtReference;
|
||||||
|
const TTypeList *members = reference ? node->getLeft()->getType().getReferentType()->getStruct() : node->getLeft()->getType().getStruct();
|
||||||
|
out.debug << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
|
||||||
|
out.debug << ": direct index for structure"; break;
|
||||||
|
}
|
||||||
case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
|
case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
|
||||||
case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
|
case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
|
||||||
|
|
||||||
|
@ -419,6 +423,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
|
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
|
||||||
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
|
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
|
||||||
|
|
||||||
|
case EOpConvUint64ToPtr: out.debug << "Convert uint64_t to pointer"; break;
|
||||||
|
case EOpConvPtrToUint64: out.debug << "Convert pointer to uint64_t"; break;
|
||||||
|
|
||||||
case EOpRadians: out.debug << "radians"; break;
|
case EOpRadians: out.debug << "radians"; break;
|
||||||
case EOpDegrees: out.debug << "degrees"; break;
|
case EOpDegrees: out.debug << "degrees"; break;
|
||||||
|
@ -674,6 +680,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
|
case EOpConstructReference: out.debug << "Construct reference type"; break;
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad unary op");
|
default: out.debug.message(EPrefixError, "Bad unary op");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,6 +816,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break;
|
case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break;
|
||||||
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
||||||
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
|
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
|
||||||
|
case EOpConstructReference: out.debug << "Construct reference"; break;
|
||||||
|
|
||||||
case EOpLessThan: out.debug << "Compare Less Than"; break;
|
case EOpLessThan: out.debug << "Compare Less Than"; break;
|
||||||
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
||||||
|
@ -871,6 +880,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpAtomicXor: out.debug << "AtomicXor"; break;
|
case EOpAtomicXor: out.debug << "AtomicXor"; break;
|
||||||
case EOpAtomicExchange: out.debug << "AtomicExchange"; break;
|
case EOpAtomicExchange: out.debug << "AtomicExchange"; break;
|
||||||
case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break;
|
case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break;
|
||||||
|
case EOpAtomicLoad: out.debug << "AtomicLoad"; break;
|
||||||
|
case EOpAtomicStore: out.debug << "AtomicStore"; break;
|
||||||
|
|
||||||
case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break;
|
case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break;
|
||||||
case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break;
|
case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break;
|
||||||
|
@ -894,6 +905,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break;
|
case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break;
|
||||||
case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break;
|
case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break;
|
||||||
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
||||||
|
case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break;
|
||||||
|
case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
||||||
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
||||||
|
@ -952,7 +965,13 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
||||||
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
|
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break;
|
||||||
|
case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break;
|
||||||
|
case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break;
|
||||||
|
case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break;
|
||||||
|
case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break;
|
||||||
|
#endif
|
||||||
case EOpAddCarry: out.debug << "addCarry"; break;
|
case EOpAddCarry: out.debug << "addCarry"; break;
|
||||||
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
||||||
case EOpUMulExtended: out.debug << "uMulExtended"; break;
|
case EOpUMulExtended: out.debug << "uMulExtended"; break;
|
||||||
|
@ -1038,6 +1057,15 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EOpTraceNV: out.debug << "traceNV"; break;
|
||||||
|
case EOpReportIntersectionNV: out.debug << "reportIntersectionNV"; break;
|
||||||
|
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
|
||||||
|
case EOpTerminateRayNV: out.debug << "terminateRayNV"; break;
|
||||||
|
case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break;
|
||||||
|
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1441,6 +1469,16 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EShLangMeshNV:
|
||||||
|
infoSink.debug << "max_vertices = " << vertices << "\n";
|
||||||
|
infoSink.debug << "max_primitives = " << primitives << "\n";
|
||||||
|
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
|
||||||
|
// Fall through
|
||||||
|
|
||||||
|
case EShLangTaskNV:
|
||||||
|
// Fall through
|
||||||
|
#endif
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
|
infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
|
||||||
{
|
{
|
||||||
|
|
|
@ -331,8 +331,14 @@ struct TResolverInOutAdaptor
|
||||||
ent.symbol->getType(),
|
ent.symbol->getType(),
|
||||||
ent.live);
|
ent.live);
|
||||||
} else {
|
} else {
|
||||||
TString errorMsg = "Invalid shader In/Out variable semantic: ";
|
TString errorMsg;
|
||||||
errorMsg += ent.symbol->getType().getQualifier().semanticName;
|
if (ent.symbol->getType().getQualifier().semanticName != nullptr) {
|
||||||
|
errorMsg = "Invalid shader In/Out variable semantic: ";
|
||||||
|
errorMsg += ent.symbol->getType().getQualifier().semanticName;
|
||||||
|
} else {
|
||||||
|
errorMsg = "Invalid shader In/Out variable: ";
|
||||||
|
errorMsg += ent.symbol->getName();
|
||||||
|
}
|
||||||
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +359,7 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
{
|
{
|
||||||
TDefaultIoResolverBase(const TIntermediate &intermediate) :
|
TDefaultIoResolverBase(const TIntermediate &intermediate) :
|
||||||
intermediate(intermediate),
|
intermediate(intermediate),
|
||||||
nextUniformLocation(0),
|
nextUniformLocation(intermediate.getUniformLocationBase()),
|
||||||
nextInputLocation(0),
|
nextInputLocation(0),
|
||||||
nextOutputLocation(0)
|
nextOutputLocation(0)
|
||||||
{ }
|
{ }
|
||||||
|
@ -428,7 +434,7 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
int resolveUniformLocation(EShLanguage /*stage*/, const char* name, const glslang::TType& type, bool /*is_live*/) override
|
||||||
{
|
{
|
||||||
// kick out of not doing this
|
// kick out of not doing this
|
||||||
if (!doAutoLocationMapping())
|
if (!doAutoLocationMapping())
|
||||||
|
@ -449,7 +455,11 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int location = nextUniformLocation;
|
int location = intermediate.getUniformLocationOverride(name);
|
||||||
|
if (location != -1)
|
||||||
|
return location;
|
||||||
|
|
||||||
|
location = nextUniformLocation;
|
||||||
|
|
||||||
nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type);
|
nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -77,12 +78,13 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
||||||
//
|
//
|
||||||
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
{
|
{
|
||||||
if (source == EShSourceNone)
|
mergeCallGraphs(infoSink, unit);
|
||||||
source = unit.source;
|
mergeModes(infoSink, unit);
|
||||||
|
mergeTrees(infoSink, unit);
|
||||||
if (source != unit.source)
|
}
|
||||||
error(infoSink, "can't link compilation units from different source languages");
|
|
||||||
|
|
||||||
|
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
|
{
|
||||||
if (unit.getNumEntryPoints() > 0) {
|
if (unit.getNumEntryPoints() > 0) {
|
||||||
if (getNumEntryPoints() > 0)
|
if (getNumEntryPoints() > 0)
|
||||||
error(infoSink, "can't handle multiple entry points per stage");
|
error(infoSink, "can't handle multiple entry points per stage");
|
||||||
|
@ -92,25 +94,75 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
numEntryPoints += unit.getNumEntryPoints();
|
numEntryPoints += unit.getNumEntryPoints();
|
||||||
|
|
||||||
|
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MERGE_MAX(member) member = std::max(member, unit.member)
|
||||||
|
#define MERGE_TRUE(member) if (unit.member) member = unit.member;
|
||||||
|
|
||||||
|
void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
|
{
|
||||||
|
if (language != unit.language)
|
||||||
|
error(infoSink, "stages must match when linking into a single stage");
|
||||||
|
|
||||||
|
if (source == EShSourceNone)
|
||||||
|
source = unit.source;
|
||||||
|
if (source != unit.source)
|
||||||
|
error(infoSink, "can't link compilation units from different source languages");
|
||||||
|
|
||||||
|
if (treeRoot == nullptr) {
|
||||||
|
profile = unit.profile;
|
||||||
|
version = unit.version;
|
||||||
|
requestedExtensions = unit.requestedExtensions;
|
||||||
|
} else {
|
||||||
|
if ((profile == EEsProfile) != (unit.profile == EEsProfile))
|
||||||
|
error(infoSink, "Cannot cross link ES and desktop profiles");
|
||||||
|
else if (unit.profile == ECompatibilityProfile)
|
||||||
|
profile = ECompatibilityProfile;
|
||||||
|
version = std::max(version, unit.version);
|
||||||
|
requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
MERGE_MAX(spvVersion.spv);
|
||||||
|
MERGE_MAX(spvVersion.vulkanGlsl);
|
||||||
|
MERGE_MAX(spvVersion.vulkan);
|
||||||
|
MERGE_MAX(spvVersion.openGl);
|
||||||
|
|
||||||
numErrors += unit.getNumErrors();
|
numErrors += unit.getNumErrors();
|
||||||
numPushConstants += unit.numPushConstants;
|
numPushConstants += unit.numPushConstants;
|
||||||
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
|
|
||||||
|
|
||||||
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
if (unit.invocations != TQualifier::layoutNotSet) {
|
||||||
error(infoSink, "gl_FragCoord redeclarations must match across shaders");
|
if (invocations == TQualifier::layoutNotSet)
|
||||||
|
invocations = unit.invocations;
|
||||||
|
else if (invocations != unit.invocations)
|
||||||
|
error(infoSink, "number of invocations must match between compilation units");
|
||||||
|
}
|
||||||
|
|
||||||
if (! earlyFragmentTests)
|
if (vertices == TQualifier::layoutNotSet)
|
||||||
earlyFragmentTests = unit.earlyFragmentTests;
|
vertices = unit.vertices;
|
||||||
|
else if (vertices != unit.vertices) {
|
||||||
if (!postDepthCoverage)
|
if (language == EShLangGeometry
|
||||||
postDepthCoverage = unit.postDepthCoverage;
|
#ifdef NV_EXTENSIONS
|
||||||
|
|| language == EShLangMeshNV
|
||||||
if (depthLayout == EldNone)
|
#endif
|
||||||
depthLayout = unit.depthLayout;
|
)
|
||||||
else if (depthLayout != unit.depthLayout)
|
error(infoSink, "Contradictory layout max_vertices values");
|
||||||
error(infoSink, "Contradictory depth layouts");
|
else if (language == EShLangTessControl)
|
||||||
|
error(infoSink, "Contradictory layout vertices values");
|
||||||
blendEquations |= unit.blendEquations;
|
else
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (primitives == TQualifier::layoutNotSet)
|
||||||
|
primitives = unit.primitives;
|
||||||
|
else if (primitives != unit.primitives) {
|
||||||
|
if (language == EShLangMeshNV)
|
||||||
|
error(infoSink, "Contradictory layout max_primitives values");
|
||||||
|
else
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
inputPrimitive = unit.inputPrimitive;
|
inputPrimitive = unit.inputPrimitive;
|
||||||
|
@ -122,16 +174,8 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
else if (outputPrimitive != unit.outputPrimitive)
|
else if (outputPrimitive != unit.outputPrimitive)
|
||||||
error(infoSink, "Contradictory output layout primitives");
|
error(infoSink, "Contradictory output layout primitives");
|
||||||
|
|
||||||
if (vertices == TQualifier::layoutNotSet)
|
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
||||||
vertices = unit.vertices;
|
error(infoSink, "gl_FragCoord redeclarations must match across shaders");
|
||||||
else if (vertices != unit.vertices) {
|
|
||||||
if (language == EShLangGeometry)
|
|
||||||
error(infoSink, "Contradictory layout max_vertices values");
|
|
||||||
else if (language == EShLangTessControl)
|
|
||||||
error(infoSink, "Contradictory layout vertices values");
|
|
||||||
else
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vertexSpacing == EvsNone)
|
if (vertexSpacing == EvsNone)
|
||||||
vertexSpacing = unit.vertexSpacing;
|
vertexSpacing = unit.vertexSpacing;
|
||||||
|
@ -143,8 +187,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
else if (vertexOrder != unit.vertexOrder)
|
else if (vertexOrder != unit.vertexOrder)
|
||||||
error(infoSink, "Contradictory triangle ordering");
|
error(infoSink, "Contradictory triangle ordering");
|
||||||
|
|
||||||
if (unit.pointMode)
|
MERGE_TRUE(pointMode);
|
||||||
pointMode = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
if (localSize[i] > 1)
|
if (localSize[i] > 1)
|
||||||
|
@ -158,48 +201,214 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
error(infoSink, "Contradictory local size specialization ids");
|
error(infoSink, "Contradictory local size specialization ids");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.xfbMode)
|
MERGE_TRUE(earlyFragmentTests);
|
||||||
xfbMode = true;
|
MERGE_TRUE(postDepthCoverage);
|
||||||
|
|
||||||
|
if (depthLayout == EldNone)
|
||||||
|
depthLayout = unit.depthLayout;
|
||||||
|
else if (depthLayout != unit.depthLayout)
|
||||||
|
error(infoSink, "Contradictory depth layouts");
|
||||||
|
|
||||||
|
MERGE_TRUE(depthReplacing);
|
||||||
|
MERGE_TRUE(hlslFunctionality1);
|
||||||
|
|
||||||
|
blendEquations |= unit.blendEquations;
|
||||||
|
|
||||||
|
MERGE_TRUE(xfbMode);
|
||||||
|
|
||||||
for (size_t b = 0; b < xfbBuffers.size(); ++b) {
|
for (size_t b = 0; b < xfbBuffers.size(); ++b) {
|
||||||
if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
|
if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
|
||||||
xfbBuffers[b].stride = unit.xfbBuffers[b].stride;
|
xfbBuffers[b].stride = unit.xfbBuffers[b].stride;
|
||||||
else if (xfbBuffers[b].stride != unit.xfbBuffers[b].stride)
|
else if (xfbBuffers[b].stride != unit.xfbBuffers[b].stride)
|
||||||
error(infoSink, "Contradictory xfb_stride");
|
error(infoSink, "Contradictory xfb_stride");
|
||||||
xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
|
xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
|
||||||
if (unit.xfbBuffers[b].containsDouble)
|
if (unit.xfbBuffers[b].contains64BitType)
|
||||||
xfbBuffers[b].containsDouble = true;
|
xfbBuffers[b].contains64BitType = true;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (unit.xfbBuffers[b].contains32BitType)
|
||||||
|
xfbBuffers[b].contains32BitType = true;
|
||||||
|
if (unit.xfbBuffers[b].contains16BitType)
|
||||||
|
xfbBuffers[b].contains16BitType = true;
|
||||||
|
#endif
|
||||||
// TODO: 4.4 link: enhanced layouts: compare ranges
|
// TODO: 4.4 link: enhanced layouts: compare ranges
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.treeRoot == 0)
|
MERGE_TRUE(multiStream);
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
MERGE_TRUE(layoutOverrideCoverage);
|
||||||
|
MERGE_TRUE(geoPassthroughEXT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) {
|
||||||
|
if (unit.shiftBinding[i] > 0)
|
||||||
|
setShiftBinding((TResourceType)i, unit.shiftBinding[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < unit.shiftBindingForSet.size(); ++i) {
|
||||||
|
for (auto it = unit.shiftBindingForSet[i].begin(); it != unit.shiftBindingForSet[i].end(); ++it)
|
||||||
|
setShiftBindingForSet((TResourceType)i, it->second, it->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceSetBinding.insert(resourceSetBinding.end(), unit.resourceSetBinding.begin(), unit.resourceSetBinding.end());
|
||||||
|
|
||||||
|
MERGE_TRUE(autoMapBindings);
|
||||||
|
MERGE_TRUE(autoMapLocations);
|
||||||
|
MERGE_TRUE(invertY);
|
||||||
|
MERGE_TRUE(flattenUniformArrays);
|
||||||
|
MERGE_TRUE(useUnknownFormat);
|
||||||
|
MERGE_TRUE(hlslOffsets);
|
||||||
|
MERGE_TRUE(useStorageBuffer);
|
||||||
|
MERGE_TRUE(hlslIoMapping);
|
||||||
|
|
||||||
|
// TODO: sourceFile
|
||||||
|
// TODO: sourceText
|
||||||
|
// TODO: processes
|
||||||
|
|
||||||
|
MERGE_TRUE(needToLegalize);
|
||||||
|
MERGE_TRUE(binaryDoubleOutput);
|
||||||
|
MERGE_TRUE(usePhysicalStorageBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Merge the 'unit' AST into 'this' AST.
|
||||||
|
// That includes rationalizing the unique IDs, which were set up independently,
|
||||||
|
// and might have overlaps that are not the same symbol, or might have different
|
||||||
|
// IDs for what should be the same shared symbol.
|
||||||
|
//
|
||||||
|
void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
|
{
|
||||||
|
if (unit.treeRoot == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (treeRoot == 0) {
|
if (treeRoot == nullptr) {
|
||||||
treeRoot = unit.treeRoot;
|
treeRoot = unit.treeRoot;
|
||||||
version = unit.version;
|
|
||||||
requestedExtensions = unit.requestedExtensions;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getting this far means we have two existing trees to merge...
|
// Getting this far means we have two existing trees to merge...
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks;
|
||||||
|
#endif
|
||||||
|
|
||||||
version = std::max(version, unit.version);
|
#ifdef NV_EXTENSIONS
|
||||||
requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
|
numTaskNVBlocks += unit.numTaskNVBlocks;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Get the top-level globals of each unit
|
// Get the top-level globals of each unit
|
||||||
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
|
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
|
||||||
TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();
|
TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();
|
||||||
|
|
||||||
// Get the linker-object lists
|
// Get the linker-object lists
|
||||||
TIntermSequence& linkerObjects = findLinkerObjects();
|
TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
|
||||||
TIntermSequence& unitLinkerObjects = unit.findLinkerObjects();
|
const TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence();
|
||||||
|
|
||||||
|
// Map by global name to unique ID to rationalize the same object having
|
||||||
|
// differing IDs in different trees.
|
||||||
|
TMap<TString, int> idMap;
|
||||||
|
int maxId;
|
||||||
|
seedIdMap(idMap, maxId);
|
||||||
|
remapIds(idMap, maxId + 1, unit);
|
||||||
|
|
||||||
mergeBodies(infoSink, globals, unitGlobals);
|
mergeBodies(infoSink, globals, unitGlobals);
|
||||||
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
|
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
|
||||||
|
|
||||||
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
|
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Traverser that seeds an ID map with all built-ins, and tracks the
|
||||||
|
// maximum ID used.
|
||||||
|
// (It would be nice to put this in a function, but that causes warnings
|
||||||
|
// on having no bodies for the copy-constructor/operator=.)
|
||||||
|
class TBuiltInIdTraverser : public TIntermTraverser {
|
||||||
|
public:
|
||||||
|
TBuiltInIdTraverser(TMap<TString, int>& idMap) : idMap(idMap), maxId(0) { }
|
||||||
|
// If it's a built in, add it to the map.
|
||||||
|
// Track the max ID.
|
||||||
|
virtual void visitSymbol(TIntermSymbol* symbol)
|
||||||
|
{
|
||||||
|
const TQualifier& qualifier = symbol->getType().getQualifier();
|
||||||
|
if (qualifier.builtIn != EbvNone)
|
||||||
|
idMap[symbol->getName()] = symbol->getId();
|
||||||
|
maxId = std::max(maxId, symbol->getId());
|
||||||
|
}
|
||||||
|
int getMaxId() const { return maxId; }
|
||||||
|
protected:
|
||||||
|
TBuiltInIdTraverser(TBuiltInIdTraverser&);
|
||||||
|
TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
|
||||||
|
TMap<TString, int>& idMap;
|
||||||
|
int maxId;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Traverser that seeds an ID map with non-builtins.
|
||||||
|
// (It would be nice to put this in a function, but that causes warnings
|
||||||
|
// on having no bodies for the copy-constructor/operator=.)
|
||||||
|
class TUserIdTraverser : public TIntermTraverser {
|
||||||
|
public:
|
||||||
|
TUserIdTraverser(TMap<TString, int>& idMap) : idMap(idMap) { }
|
||||||
|
// If its a non-built-in global, add it to the map.
|
||||||
|
virtual void visitSymbol(TIntermSymbol* symbol)
|
||||||
|
{
|
||||||
|
const TQualifier& qualifier = symbol->getType().getQualifier();
|
||||||
|
if (qualifier.builtIn == EbvNone)
|
||||||
|
idMap[symbol->getName()] = symbol->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TUserIdTraverser(TUserIdTraverser&);
|
||||||
|
TUserIdTraverser& operator=(TUserIdTraverser&);
|
||||||
|
TMap<TString, int>& idMap; // over biggest id
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize the the ID map with what we know of 'this' AST.
|
||||||
|
void TIntermediate::seedIdMap(TMap<TString, int>& idMap, int& maxId)
|
||||||
|
{
|
||||||
|
// all built-ins everywhere need to align on IDs and contribute to the max ID
|
||||||
|
TBuiltInIdTraverser builtInIdTraverser(idMap);
|
||||||
|
treeRoot->traverse(&builtInIdTraverser);
|
||||||
|
maxId = builtInIdTraverser.getMaxId();
|
||||||
|
|
||||||
|
// user variables in the linker object list need to align on ids
|
||||||
|
TUserIdTraverser userIdTraverser(idMap);
|
||||||
|
findLinkerObjects()->traverse(&userIdTraverser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverser to map an AST ID to what was known from the seeding AST.
|
||||||
|
// (It would be nice to put this in a function, but that causes warnings
|
||||||
|
// on having no bodies for the copy-constructor/operator=.)
|
||||||
|
class TRemapIdTraverser : public TIntermTraverser {
|
||||||
|
public:
|
||||||
|
TRemapIdTraverser(const TMap<TString, int>& idMap, int idShift) : idMap(idMap), idShift(idShift) { }
|
||||||
|
// Do the mapping:
|
||||||
|
// - if the same symbol, adopt the 'this' ID
|
||||||
|
// - otherwise, ensure a unique ID by shifting to a new space
|
||||||
|
virtual void visitSymbol(TIntermSymbol* symbol)
|
||||||
|
{
|
||||||
|
const TQualifier& qualifier = symbol->getType().getQualifier();
|
||||||
|
bool remapped = false;
|
||||||
|
if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) {
|
||||||
|
auto it = idMap.find(symbol->getName());
|
||||||
|
if (it != idMap.end()) {
|
||||||
|
symbol->changeId(it->second);
|
||||||
|
remapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!remapped)
|
||||||
|
symbol->changeId(symbol->getId() + idShift);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
TRemapIdTraverser(TRemapIdTraverser&);
|
||||||
|
TRemapIdTraverser& operator=(TRemapIdTraverser&);
|
||||||
|
const TMap<TString, int>& idMap;
|
||||||
|
int idShift;
|
||||||
|
};
|
||||||
|
|
||||||
|
void TIntermediate::remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate& unit)
|
||||||
|
{
|
||||||
|
// Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
|
||||||
|
TRemapIdTraverser idTraverser(idMap, idShift);
|
||||||
|
unit.getTreeRoot()->traverse(&idTraverser);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Merge the function bodies and global-level initializers from unitGlobals into globals.
|
// Merge the function bodies and global-level initializers from unitGlobals into globals.
|
||||||
// Will error check duplication of function bodies for the same signature.
|
// Will error check duplication of function bodies for the same signature.
|
||||||
|
@ -344,11 +553,16 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory...
|
// Memory...
|
||||||
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
|
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
|
||||||
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
|
symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent ||
|
||||||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
|
symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
|
||||||
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
|
symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
|
||||||
symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
|
symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
|
||||||
|
symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
|
||||||
|
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
|
||||||
|
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
|
||||||
|
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
|
||||||
|
symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
|
||||||
error(infoSink, "Memory qualifiers must match:");
|
error(infoSink, "Memory qualifiers must match:");
|
||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
}
|
}
|
||||||
|
@ -426,8 +640,14 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||||
error(infoSink, "Cannot use both gl_FragColor and gl_FragData");
|
error(infoSink, "Cannot use both gl_FragColor and gl_FragData");
|
||||||
|
|
||||||
for (size_t b = 0; b < xfbBuffers.size(); ++b) {
|
for (size_t b = 0; b < xfbBuffers.size(); ++b) {
|
||||||
if (xfbBuffers[b].containsDouble)
|
if (xfbBuffers[b].contains64BitType)
|
||||||
RoundToPow2(xfbBuffers[b].implicitStride, 8);
|
RoundToPow2(xfbBuffers[b].implicitStride, 8);
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
else if (xfbBuffers[b].contains32BitType)
|
||||||
|
RoundToPow2(xfbBuffers[b].implicitStride, 4);
|
||||||
|
else if (xfbBuffers[b].contains16BitType)
|
||||||
|
RoundToPow2(xfbBuffers[b].implicitStride, 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
// "It is a compile-time or link-time error to have
|
// "It is a compile-time or link-time error to have
|
||||||
// any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
|
// any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
|
||||||
|
@ -442,18 +662,31 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||||
xfbBuffers[b].stride = xfbBuffers[b].implicitStride;
|
xfbBuffers[b].stride = xfbBuffers[b].implicitStride;
|
||||||
|
|
||||||
// "If the buffer is capturing any
|
// "If the buffer is capturing any
|
||||||
// outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a
|
// outputs with double-precision or 64-bit integer components, the stride must be a multiple of 8, otherwise it must be a
|
||||||
// multiple of 4, or a compile-time or link-time error results."
|
// multiple of 4, or a compile-time or link-time error results."
|
||||||
if (xfbBuffers[b].containsDouble && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) {
|
if (xfbBuffers[b].contains64BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) {
|
||||||
error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double:");
|
error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double or 64-bit integer:");
|
||||||
infoSink.info.prefix(EPrefixError);
|
infoSink.info.prefix(EPrefixError);
|
||||||
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (xfbBuffers[b].contains32BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
|
||||||
|
#else
|
||||||
} else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
|
} else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
|
||||||
|
#endif
|
||||||
error(infoSink, "xfb_stride must be multiple of 4:");
|
error(infoSink, "xfb_stride must be multiple of 4:");
|
||||||
infoSink.info.prefix(EPrefixError);
|
infoSink.info.prefix(EPrefixError);
|
||||||
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
||||||
}
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
// "If the buffer is capturing any
|
||||||
|
// outputs with half-precision or 16-bit integer components, the stride must be a multiple of 2"
|
||||||
|
else if (xfbBuffers[b].contains16BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 2)) {
|
||||||
|
error(infoSink, "xfb_stride must be multiple of 2 for buffer holding a half float or 16-bit integer:");
|
||||||
|
infoSink.info.prefix(EPrefixError);
|
||||||
|
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||||
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
|
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
|
||||||
if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
|
if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
|
||||||
|
@ -483,17 +716,9 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||||
case EShLangGeometry:
|
case EShLangGeometry:
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
error(infoSink, "At least one shader must specify an input layout primitive");
|
error(infoSink, "At least one shader must specify an input layout primitive");
|
||||||
if (outputPrimitive == ElgNone
|
if (outputPrimitive == ElgNone)
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
&& !getGeoPassthroughEXT()
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
error(infoSink, "At least one shader must specify an output layout primitive");
|
error(infoSink, "At least one shader must specify an output layout primitive");
|
||||||
if (vertices == TQualifier::layoutNotSet
|
if (vertices == TQualifier::layoutNotSet)
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
&& !getGeoPassthroughEXT()
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
|
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
|
||||||
break;
|
break;
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
|
@ -505,6 +730,42 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||||
break;
|
break;
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EShLangRayGenNV:
|
||||||
|
case EShLangIntersectNV:
|
||||||
|
case EShLangAnyHitNV:
|
||||||
|
case EShLangClosestHitNV:
|
||||||
|
case EShLangMissNV:
|
||||||
|
case EShLangCallableNV:
|
||||||
|
if (numShaderRecordNVBlocks > 1)
|
||||||
|
error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage");
|
||||||
|
break;
|
||||||
|
case EShLangMeshNV:
|
||||||
|
// NV_mesh_shader doesn't allow use of both single-view and per-view builtins.
|
||||||
|
if (inIoAccessed("gl_Position") && inIoAccessed("gl_PositionPerViewNV"))
|
||||||
|
error(infoSink, "Can only use one of gl_Position or gl_PositionPerViewNV");
|
||||||
|
if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipDistancePerViewNV"))
|
||||||
|
error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipDistancePerViewNV");
|
||||||
|
if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_CullDistancePerViewNV"))
|
||||||
|
error(infoSink, "Can only use one of gl_CullDistance or gl_CullDistancePerViewNV");
|
||||||
|
if (inIoAccessed("gl_Layer") && inIoAccessed("gl_LayerPerViewNV"))
|
||||||
|
error(infoSink, "Can only use one of gl_Layer or gl_LayerPerViewNV");
|
||||||
|
if (inIoAccessed("gl_ViewportMask") && inIoAccessed("gl_ViewportMaskPerViewNV"))
|
||||||
|
error(infoSink, "Can only use one of gl_ViewportMask or gl_ViewportMaskPerViewNV");
|
||||||
|
if (outputPrimitive == ElgNone)
|
||||||
|
error(infoSink, "At least one shader must specify an output layout primitive");
|
||||||
|
if (vertices == TQualifier::layoutNotSet)
|
||||||
|
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
|
||||||
|
if (primitives == TQualifier::layoutNotSet)
|
||||||
|
error(infoSink, "At least one shader must specify a layout(max_primitives = value)");
|
||||||
|
// fall through
|
||||||
|
case EShLangTaskNV:
|
||||||
|
if (numTaskNVBlocks > 1)
|
||||||
|
error(infoSink, "Only one taskNV interface block is allowed per shader");
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error(infoSink, "Unknown Stage.");
|
error(infoSink, "Unknown Stage.");
|
||||||
break;
|
break;
|
||||||
|
@ -699,7 +960,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
|
||||||
|
|
||||||
// TODO: linker functionality: location collision checking
|
// TODO: linker functionality: location collision checking
|
||||||
|
|
||||||
TIntermSequence& linkObjects = findLinkerObjects();
|
TIntermSequence& linkObjects = findLinkerObjects()->getSequence();
|
||||||
for (size_t i = 0; i < linkObjects.size(); ++i) {
|
for (size_t i = 0; i < linkObjects.size(); ++i) {
|
||||||
const TType& type = linkObjects[i]->getAsTyped()->getType();
|
const TType& type = linkObjects[i]->getAsTyped()->getType();
|
||||||
const TQualifier& qualifier = type.getQualifier();
|
const TQualifier& qualifier = type.getQualifier();
|
||||||
|
@ -718,7 +979,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TIntermSequence& TIntermediate::findLinkerObjects() const
|
TIntermAggregate* TIntermediate::findLinkerObjects() const
|
||||||
{
|
{
|
||||||
// Get the top-level globals
|
// Get the top-level globals
|
||||||
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
|
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
|
||||||
|
@ -726,7 +987,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const
|
||||||
// Get the last member of the sequences, expected to be the linker-object lists
|
// Get the last member of the sequences, expected to be the linker-object lists
|
||||||
assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);
|
assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);
|
||||||
|
|
||||||
return globals.back()->getAsAggregate()->getSequence();
|
return globals.back()->getAsAggregate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if a variable was both a user-declared output and used.
|
// See if a variable was both a user-declared output and used.
|
||||||
|
@ -734,7 +995,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const
|
||||||
// is more useful, and perhaps the spec should be changed to reflect that.
|
// is more useful, and perhaps the spec should be changed to reflect that.
|
||||||
bool TIntermediate::userOutputUsed() const
|
bool TIntermediate::userOutputUsed() const
|
||||||
{
|
{
|
||||||
const TIntermSequence& linkerObjects = findLinkerObjects();
|
const TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (size_t i = 0; i < linkerObjects.size(); ++i) {
|
for (size_t i = 0; i < linkerObjects.size(); ++i) {
|
||||||
|
@ -775,7 +1036,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
if (qualifier.isUniformOrBuffer()) {
|
if (qualifier.isUniformOrBuffer() || qualifier.isTaskMemory()) {
|
||||||
if (type.isSizedArray())
|
if (type.isSizedArray())
|
||||||
size = type.getCumulativeArraySize();
|
size = type.getCumulativeArraySize();
|
||||||
else
|
else
|
||||||
|
@ -926,10 +1187,19 @@ int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage)
|
||||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
// TODO: are there valid cases of having an unsized array with a location? If so, running this code too early.
|
// TODO: are there valid cases of having an unsized array with a location? If so, running this code too early.
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
if (type.isSizedArray())
|
if (type.isSizedArray()
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
&& !type.getQualifier().isPerView()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
|
return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
|
||||||
else
|
else {
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];"
|
||||||
|
elementType.getQualifier().perViewNV = false;
|
||||||
|
#endif
|
||||||
return computeTypeLocationSize(elementType, stage);
|
return computeTypeLocationSize(elementType, stage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "The locations consumed by block and structure members are determined by applying the rules above
|
// "The locations consumed by block and structure members are determined by applying the rules above
|
||||||
|
@ -1015,7 +1285,11 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
|
||||||
TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer];
|
TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer];
|
||||||
|
|
||||||
// compute the range
|
// compute the range
|
||||||
unsigned int size = computeTypeXfbSize(type, buffer.containsDouble);
|
#ifdef AMD_EXTENSIONS
|
||||||
|
unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType, buffer.contains32BitType, buffer.contains16BitType);
|
||||||
|
#else
|
||||||
|
unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType);
|
||||||
|
#endif
|
||||||
buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size);
|
buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size);
|
||||||
TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1);
|
TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1);
|
||||||
|
|
||||||
|
@ -1034,11 +1308,18 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
|
||||||
|
|
||||||
// Recursively figure out how many bytes of xfb buffer are used by the given type.
|
// Recursively figure out how many bytes of xfb buffer are used by the given type.
|
||||||
// Return the size of type, in bytes.
|
// Return the size of type, in bytes.
|
||||||
// Sets containsDouble to true if the type contains a double.
|
// Sets contains64BitType to true if the type contains a 64-bit data type.
|
||||||
// N.B. Caller must set containsDouble to false before calling.
|
#ifdef AMD_EXTENSIONS
|
||||||
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const
|
// Sets contains32BitType to true if the type contains a 32-bit data type.
|
||||||
|
// Sets contains16BitType to true if the type contains a 16-bit data type.
|
||||||
|
// N.B. Caller must set contains64BitType, contains32BitType, and contains16BitType to false before calling.
|
||||||
|
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const
|
||||||
|
#else
|
||||||
|
// N.B. Caller must set contains64BitType to false before calling.
|
||||||
|
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType) const
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// "...if applied to an aggregate containing a double, the offset must also be a multiple of 8,
|
// "...if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
|
||||||
// and the space taken in the buffer will be a multiple of 8.
|
// and the space taken in the buffer will be a multiple of 8.
|
||||||
// ...within the qualified entity, subsequent components are each
|
// ...within the qualified entity, subsequent components are each
|
||||||
// assigned, in order, to the next available offset aligned to a multiple of
|
// assigned, in order, to the next available offset aligned to a multiple of
|
||||||
|
@ -1049,29 +1330,59 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
||||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
assert(type.isSizedArray());
|
assert(type.isSizedArray());
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble);
|
#ifdef AMD_EXTENSIONS
|
||||||
|
return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType);
|
||||||
|
#else
|
||||||
|
return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.isStruct()) {
|
if (type.isStruct()) {
|
||||||
unsigned int size = 0;
|
unsigned int size = 0;
|
||||||
bool structContainsDouble = false;
|
bool structContains64BitType = false;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool structContains32BitType = false;
|
||||||
|
bool structContains16BitType = false;
|
||||||
|
#endif
|
||||||
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
||||||
TType memberType(type, member);
|
TType memberType(type, member);
|
||||||
// "... if applied to
|
// "... if applied to
|
||||||
// an aggregate containing a double, the offset must also be a multiple of 8,
|
// an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
|
||||||
// and the space taken in the buffer will be a multiple of 8."
|
// and the space taken in the buffer will be a multiple of 8."
|
||||||
bool memberContainsDouble = false;
|
bool memberContains64BitType = false;
|
||||||
int memberSize = computeTypeXfbSize(memberType, memberContainsDouble);
|
#ifdef AMD_EXTENSIONS
|
||||||
if (memberContainsDouble) {
|
bool memberContains32BitType = false;
|
||||||
structContainsDouble = true;
|
bool memberContains16BitType = false;
|
||||||
|
int memberSize = computeTypeXfbSize(memberType, memberContains64BitType, memberContains32BitType, memberContains16BitType);
|
||||||
|
#else
|
||||||
|
int memberSize = computeTypeXfbSize(memberType, memberContains64BitType);
|
||||||
|
#endif
|
||||||
|
if (memberContains64BitType) {
|
||||||
|
structContains64BitType = true;
|
||||||
RoundToPow2(size, 8);
|
RoundToPow2(size, 8);
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (memberContains32BitType) {
|
||||||
|
structContains32BitType = true;
|
||||||
|
RoundToPow2(size, 4);
|
||||||
|
} else if (memberContains16BitType) {
|
||||||
|
structContains16BitType = true;
|
||||||
|
RoundToPow2(size, 2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
size += memberSize;
|
size += memberSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (structContainsDouble) {
|
if (structContains64BitType) {
|
||||||
containsDouble = true;
|
contains64BitType = true;
|
||||||
RoundToPow2(size, 8);
|
RoundToPow2(size, 8);
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (structContains32BitType) {
|
||||||
|
contains32BitType = true;
|
||||||
|
RoundToPow2(size, 4);
|
||||||
|
} else if (structContains16BitType) {
|
||||||
|
contains16BitType = true;
|
||||||
|
RoundToPow2(size, 2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -1088,11 +1399,23 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
||||||
numComponents = 1;
|
numComponents = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.getBasicType() == EbtDouble) {
|
if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) {
|
||||||
containsDouble = true;
|
contains64BitType = true;
|
||||||
return 8 * numComponents;
|
return 8 * numComponents;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (type.getBasicType() == EbtFloat16 || type.getBasicType() == EbtInt16 || type.getBasicType() == EbtUint16) {
|
||||||
|
contains16BitType = true;
|
||||||
|
return 2 * numComponents;
|
||||||
|
} else if (type.getBasicType() == EbtInt8 || type.getBasicType() == EbtUint8)
|
||||||
|
return numComponents;
|
||||||
|
else {
|
||||||
|
contains32BitType = true;
|
||||||
|
return 4 * numComponents;
|
||||||
|
}
|
||||||
|
#else
|
||||||
} else
|
} else
|
||||||
return 4 * numComponents;
|
return 4 * numComponents;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const int baseAlignmentVec4Std140 = 16;
|
const int baseAlignmentVec4Std140 = 16;
|
||||||
|
@ -1111,6 +1434,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
||||||
case EbtUint8: size = 1; return 1;
|
case EbtUint8: size = 1; return 1;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16: size = 2; return 2;
|
case EbtUint16: size = 2; return 2;
|
||||||
|
case EbtReference: size = 8; return 8;
|
||||||
default: size = 4; return 4;
|
default: size = 4; return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1129,10 +1453,11 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
||||||
// stride comes from the flattening down to vectors.
|
// stride comes from the flattening down to vectors.
|
||||||
//
|
//
|
||||||
// Return value is the alignment of the type.
|
// Return value is the alignment of the type.
|
||||||
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, bool std140, bool rowMajor)
|
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor)
|
||||||
{
|
{
|
||||||
int alignment;
|
int alignment;
|
||||||
|
|
||||||
|
bool std140 = layoutPacking == glslang::ElpStd140;
|
||||||
// When using the std140 storage layout, structures will be laid out in buffer
|
// When using the std140 storage layout, structures will be laid out in buffer
|
||||||
// storage with its members stored in monotonically increasing order based on their
|
// storage with its members stored in monotonically increasing order based on their
|
||||||
// location in the declaration. A structure and each structure member have a base
|
// location in the declaration. A structure and each structure member have a base
|
||||||
|
@ -1196,7 +1521,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||||
if (type.isArray()) {
|
if (type.isArray()) {
|
||||||
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
TType derefType(type, 0);
|
TType derefType(type, 0);
|
||||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor);
|
||||||
if (std140)
|
if (std140)
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
RoundToPow2(size, alignment);
|
RoundToPow2(size, alignment);
|
||||||
|
@ -1216,7 +1541,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||||
int memberSize;
|
int memberSize;
|
||||||
// modify just the children's view of matrix layout, if there is one for this member
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
||||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140,
|
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, layoutPacking,
|
||||||
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||||
RoundToPow2(size, memberAlignment);
|
RoundToPow2(size, memberAlignment);
|
||||||
|
@ -1255,7 +1580,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||||
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
||||||
TType derefType(type, 0, rowMajor);
|
TType derefType(type, 0, rowMajor);
|
||||||
|
|
||||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor);
|
||||||
if (std140)
|
if (std140)
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
RoundToPow2(size, alignment);
|
RoundToPow2(size, alignment);
|
||||||
|
@ -1283,4 +1608,79 @@ bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
|
||||||
: offset % 16 != 0;
|
: offset % 16 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride, bool rowMajor)
|
||||||
|
{
|
||||||
|
int alignment;
|
||||||
|
|
||||||
|
stride = 0;
|
||||||
|
int dummyStride;
|
||||||
|
|
||||||
|
if (type.isArray()) {
|
||||||
|
TType derefType(type, 0);
|
||||||
|
alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor);
|
||||||
|
|
||||||
|
stride = size;
|
||||||
|
RoundToPow2(stride, alignment);
|
||||||
|
|
||||||
|
size = stride * (type.getOuterArraySize() - 1) + size;
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.getBasicType() == EbtStruct) {
|
||||||
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
int maxAlignment = 0;
|
||||||
|
for (size_t m = 0; m < memberList.size(); ++m) {
|
||||||
|
int memberSize;
|
||||||
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
|
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
||||||
|
int memberAlignment = getScalarAlignment(*memberList[m].type, memberSize, dummyStride,
|
||||||
|
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||||
|
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||||
|
RoundToPow2(size, memberAlignment);
|
||||||
|
size += memberSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.isScalar())
|
||||||
|
return getBaseAlignmentScalar(type, size);
|
||||||
|
|
||||||
|
if (type.isVector()) {
|
||||||
|
int scalarAlign = getBaseAlignmentScalar(type, size);
|
||||||
|
|
||||||
|
size *= type.getVectorSize();
|
||||||
|
return scalarAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.isMatrix()) {
|
||||||
|
TType derefType(type, 0, rowMajor);
|
||||||
|
|
||||||
|
alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor);
|
||||||
|
|
||||||
|
stride = size; // use intra-matrix stride for stride of a just a matrix
|
||||||
|
if (rowMajor)
|
||||||
|
size = stride * type.getMatrixRows();
|
||||||
|
else
|
||||||
|
size = stride * type.getMatrixCols();
|
||||||
|
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0); // all cases should be covered above
|
||||||
|
size = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TIntermediate::getMemberAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor)
|
||||||
|
{
|
||||||
|
if (layoutPacking == glslang::ElpScalar) {
|
||||||
|
return getScalarAlignment(type, size, stride, rowMajor);
|
||||||
|
} else {
|
||||||
|
return getBaseAlignment(type, size, stride, layoutPacking, rowMajor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2016 LunarG, Inc.
|
// Copyright (C) 2016 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -41,6 +43,8 @@
|
||||||
#include "../Public/ShaderLang.h"
|
#include "../Public/ShaderLang.h"
|
||||||
#include "Versions.h"
|
#include "Versions.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -145,11 +149,20 @@ struct TOffsetRange {
|
||||||
|
|
||||||
// Things that need to be tracked per xfb buffer.
|
// Things that need to be tracked per xfb buffer.
|
||||||
struct TXfbBuffer {
|
struct TXfbBuffer {
|
||||||
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), containsDouble(false) { }
|
#ifdef AMD_EXTENSIONS
|
||||||
|
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false),
|
||||||
|
contains32BitType(false), contains16BitType(false) { }
|
||||||
|
#else
|
||||||
|
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false) { }
|
||||||
|
#endif
|
||||||
std::vector<TRange> ranges; // byte offsets that have already been assigned
|
std::vector<TRange> ranges; // byte offsets that have already been assigned
|
||||||
unsigned int stride;
|
unsigned int stride;
|
||||||
unsigned int implicitStride;
|
unsigned int implicitStride;
|
||||||
bool containsDouble;
|
bool contains64BitType;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool contains32BitType;
|
||||||
|
bool contains16BitType;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Track a set of strings describing how the module was processed.
|
// Track a set of strings describing how the module was processed.
|
||||||
|
@ -204,6 +217,17 @@ class TSymbolTable;
|
||||||
class TSymbol;
|
class TSymbol;
|
||||||
class TVariable;
|
class TVariable;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
//
|
||||||
|
// Texture and Sampler transformation mode.
|
||||||
|
//
|
||||||
|
enum ComputeDerivativeMode {
|
||||||
|
LayoutDerivativeNone, // default layout as SPV_NV_compute_shader_derivatives not enabled
|
||||||
|
LayoutDerivativeGroupQuads, // derivative_group_quadsNV
|
||||||
|
LayoutDerivativeGroupLinear, // derivative_group_linearNV
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set of helper functions to help parse and build the tree.
|
// Set of helper functions to help parse and build the tree.
|
||||||
//
|
//
|
||||||
|
@ -223,6 +247,10 @@ public:
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
layoutOverrideCoverage(false),
|
layoutOverrideCoverage(false),
|
||||||
geoPassthroughEXT(false),
|
geoPassthroughEXT(false),
|
||||||
|
numShaderRecordNVBlocks(0),
|
||||||
|
computeDerivativeMode(LayoutDerivativeNone),
|
||||||
|
primitives(TQualifier::layoutNotSet),
|
||||||
|
numTaskNVBlocks(0),
|
||||||
#endif
|
#endif
|
||||||
autoMapBindings(false),
|
autoMapBindings(false),
|
||||||
autoMapLocations(false),
|
autoMapLocations(false),
|
||||||
|
@ -231,10 +259,13 @@ public:
|
||||||
useUnknownFormat(false),
|
useUnknownFormat(false),
|
||||||
hlslOffsets(false),
|
hlslOffsets(false),
|
||||||
useStorageBuffer(false),
|
useStorageBuffer(false),
|
||||||
|
useVulkanMemoryModel(false),
|
||||||
hlslIoMapping(false),
|
hlslIoMapping(false),
|
||||||
textureSamplerTransformMode(EShTexSampTransKeep),
|
textureSamplerTransformMode(EShTexSampTransKeep),
|
||||||
needToLegalize(false),
|
needToLegalize(false),
|
||||||
binaryDoubleOutput(false)
|
binaryDoubleOutput(false),
|
||||||
|
usePhysicalStorageBuffer(false),
|
||||||
|
uniformLocationBase(0)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
|
@ -349,7 +380,7 @@ public:
|
||||||
if (hlslOffsets)
|
if (hlslOffsets)
|
||||||
processes.addProcess("hlsl-offsets");
|
processes.addProcess("hlsl-offsets");
|
||||||
}
|
}
|
||||||
bool usingHlslOFfsets() const { return hlslOffsets; }
|
bool usingHlslOffsets() const { return hlslOffsets; }
|
||||||
void setUseStorageBuffer()
|
void setUseStorageBuffer()
|
||||||
{
|
{
|
||||||
useStorageBuffer = true;
|
useStorageBuffer = true;
|
||||||
|
@ -363,6 +394,17 @@ public:
|
||||||
processes.addProcess("hlsl-iomap");
|
processes.addProcess("hlsl-iomap");
|
||||||
}
|
}
|
||||||
bool usingHlslIoMapping() { return hlslIoMapping; }
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
void setUseVulkanMemoryModel()
|
||||||
|
{
|
||||||
|
useVulkanMemoryModel = true;
|
||||||
|
processes.addProcess("use-vulkan-memory-model");
|
||||||
|
}
|
||||||
|
bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
|
||||||
|
void setUsePhysicalStorageBuffer()
|
||||||
|
{
|
||||||
|
usePhysicalStorageBuffer = true;
|
||||||
|
}
|
||||||
|
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
|
||||||
|
|
||||||
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
||||||
bool hasCounterBufferName(const TString& name) const {
|
bool hasCounterBufferName(const TString& name) const {
|
||||||
|
@ -387,11 +429,40 @@ public:
|
||||||
if (spvVersion.openGl > 0)
|
if (spvVersion.openGl > 0)
|
||||||
processes.addProcess("client opengl100");
|
processes.addProcess("client opengl100");
|
||||||
|
|
||||||
|
// target SPV
|
||||||
|
switch (spvVersion.spv) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case EShTargetSpv_1_0:
|
||||||
|
break;
|
||||||
|
case EShTargetSpv_1_1:
|
||||||
|
processes.addProcess("target-env spirv1.1");
|
||||||
|
break;
|
||||||
|
case EShTargetSpv_1_2:
|
||||||
|
processes.addProcess("target-env spirv1.2");
|
||||||
|
break;
|
||||||
|
case EShTargetSpv_1_3:
|
||||||
|
processes.addProcess("target-env spirv1.3");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
processes.addProcess("target-env spirvUnknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// target-environment processes
|
// target-environment processes
|
||||||
if (spvVersion.vulkan > 0)
|
switch (spvVersion.vulkan) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case EShTargetVulkan_1_0:
|
||||||
processes.addProcess("target-env vulkan1.0");
|
processes.addProcess("target-env vulkan1.0");
|
||||||
else if (spvVersion.vulkan > 0)
|
break;
|
||||||
|
case EShTargetVulkan_1_1:
|
||||||
|
processes.addProcess("target-env vulkan1.1");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
processes.addProcess("target-env vulkanUnknown");
|
processes.addProcess("target-env vulkanUnknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (spvVersion.openGl > 0)
|
if (spvVersion.openGl > 0)
|
||||||
processes.addProcess("target-env opengl");
|
processes.addProcess("target-env opengl");
|
||||||
}
|
}
|
||||||
|
@ -406,6 +477,11 @@ public:
|
||||||
int getNumEntryPoints() const { return numEntryPoints; }
|
int getNumEntryPoints() const { return numEntryPoints; }
|
||||||
int getNumErrors() const { return numErrors; }
|
int getNumErrors() const { return numErrors; }
|
||||||
void addPushConstantCount() { ++numPushConstants; }
|
void addPushConstantCount() { ++numPushConstants; }
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
|
||||||
|
void addTaskNVCount() { ++numTaskNVBlocks; }
|
||||||
|
#endif
|
||||||
|
|
||||||
bool isRecursive() const { return recursive; }
|
bool isRecursive() const { return recursive; }
|
||||||
|
|
||||||
TIntermSymbol* addSymbol(const TVariable&);
|
TIntermSymbol* addSymbol(const TVariable&);
|
||||||
|
@ -602,9 +678,15 @@ public:
|
||||||
}
|
}
|
||||||
unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
|
unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
|
||||||
int addXfbBufferOffset(const TType&);
|
int addXfbBufferOffset(const TType&);
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
#ifdef AMD_EXTENSIONS
|
||||||
|
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
|
||||||
|
#else
|
||||||
|
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
|
||||||
|
#endif
|
||||||
static int getBaseAlignmentScalar(const TType&, int& size);
|
static int getBaseAlignmentScalar(const TType&, int& size);
|
||||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||||
|
static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
|
||||||
|
static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||||
static bool improperStraddle(const TType& type, int size, int offset);
|
static bool improperStraddle(const TType& type, int size, int offset);
|
||||||
bool promote(TIntermOperator*);
|
bool promote(TIntermOperator*);
|
||||||
|
|
||||||
|
@ -613,6 +695,16 @@ public:
|
||||||
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
||||||
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
|
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
|
||||||
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
||||||
|
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
|
||||||
|
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
|
||||||
|
bool setPrimitives(int m)
|
||||||
|
{
|
||||||
|
if (primitives != TQualifier::layoutNotSet)
|
||||||
|
return primitives == m;
|
||||||
|
primitives = m;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int getPrimitives() const { return primitives; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* addSemanticName(const TString& name)
|
const char* addSemanticName(const TString& name)
|
||||||
|
@ -622,9 +714,12 @@ public:
|
||||||
|
|
||||||
void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
|
void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
|
||||||
const std::string& getSourceFile() const { return sourceFile; }
|
const std::string& getSourceFile() const { return sourceFile; }
|
||||||
void addSourceText(const char* text) { sourceText = sourceText + text; }
|
void addSourceText(const char* text, size_t len) { sourceText.append(text, len); }
|
||||||
const std::string& getSourceText() const { return sourceText; }
|
const std::string& getSourceText() const { return sourceText; }
|
||||||
void addProcesses(const std::vector<std::string>& p) {
|
const std::map<std::string, std::string>& getIncludeText() const { return includeText; }
|
||||||
|
void addIncludeText(const char* name, const char* text, size_t len) { includeText[name].assign(text,len); }
|
||||||
|
void addProcesses(const std::vector<std::string>& p)
|
||||||
|
{
|
||||||
for (int i = 0; i < (int)p.size(); ++i)
|
for (int i = 0; i < (int)p.size(); ++i)
|
||||||
processes.addProcess(p[i]);
|
processes.addProcess(p[i]);
|
||||||
}
|
}
|
||||||
|
@ -632,6 +727,25 @@ public:
|
||||||
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
|
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
|
||||||
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
|
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
|
||||||
|
|
||||||
|
void addUniformLocationOverride(const char* nameStr, int location)
|
||||||
|
{
|
||||||
|
std::string name = nameStr;
|
||||||
|
uniformLocationOverrides[name] = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getUniformLocationOverride(const char* nameStr) const
|
||||||
|
{
|
||||||
|
std::string name = nameStr;
|
||||||
|
auto pos = uniformLocationOverrides.find(name);
|
||||||
|
if (pos == uniformLocationOverrides.end())
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return pos->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUniformLocationBase(int base) { uniformLocationBase = base; }
|
||||||
|
int getUniformLocationBase() const { return uniformLocationBase; }
|
||||||
|
|
||||||
void setNeedsLegalization() { needToLegalize = true; }
|
void setNeedsLegalization() { needToLegalize = true; }
|
||||||
bool needsLegalization() const { return needToLegalize; }
|
bool needsLegalization() const { return needToLegalize; }
|
||||||
|
|
||||||
|
@ -645,6 +759,11 @@ protected:
|
||||||
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||||
void error(TInfoSink& infoSink, const char*);
|
void error(TInfoSink& infoSink, const char*);
|
||||||
void warn(TInfoSink& infoSink, const char*);
|
void warn(TInfoSink& infoSink, const char*);
|
||||||
|
void mergeCallGraphs(TInfoSink&, TIntermediate&);
|
||||||
|
void mergeModes(TInfoSink&, TIntermediate&);
|
||||||
|
void mergeTrees(TInfoSink&, TIntermediate&);
|
||||||
|
void seedIdMap(TMap<TString, int>& idMap, int& maxId);
|
||||||
|
void remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate&);
|
||||||
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
|
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
|
||||||
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
|
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
|
||||||
void mergeImplicitArraySizes(TType&, const TType&);
|
void mergeImplicitArraySizes(TType&, const TType&);
|
||||||
|
@ -652,7 +771,7 @@ protected:
|
||||||
void checkCallGraphCycles(TInfoSink&);
|
void checkCallGraphCycles(TInfoSink&);
|
||||||
void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
|
void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
|
||||||
void inOutLocationCheck(TInfoSink&);
|
void inOutLocationCheck(TInfoSink&);
|
||||||
TIntermSequence& findLinkerObjects() const;
|
TIntermAggregate* findLinkerObjects() const;
|
||||||
bool userOutputUsed() const;
|
bool userOutputUsed() const;
|
||||||
bool isSpecializationOperation(const TIntermOperator&) const;
|
bool isSpecializationOperation(const TIntermOperator&) const;
|
||||||
bool isNonuniformPropagating(TOperator) const;
|
bool isNonuniformPropagating(TOperator) const;
|
||||||
|
@ -665,7 +784,7 @@ protected:
|
||||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||||
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||||
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
|
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
|
||||||
TIntermUnary* createConversion(TBasicType convertTo, TIntermTyped* node) const;
|
TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
|
||||||
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
|
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
|
||||||
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
|
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
|
||||||
static const char* getResourceName(TResourceType);
|
static const char* getResourceName(TResourceType);
|
||||||
|
@ -674,6 +793,8 @@ protected:
|
||||||
EShSource source; // source language, known a bit later
|
EShSource source; // source language, known a bit later
|
||||||
std::string entryPointName;
|
std::string entryPointName;
|
||||||
std::string entryPointMangledName;
|
std::string entryPointMangledName;
|
||||||
|
typedef std::list<TCall> TGraph;
|
||||||
|
TGraph callGraph;
|
||||||
|
|
||||||
EProfile profile; // source profile
|
EProfile profile; // source profile
|
||||||
int version; // source version
|
int version; // source version
|
||||||
|
@ -703,18 +824,23 @@ protected:
|
||||||
bool hlslFunctionality1;
|
bool hlslFunctionality1;
|
||||||
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
||||||
bool xfbMode;
|
bool xfbMode;
|
||||||
|
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
||||||
bool multiStream;
|
bool multiStream;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
bool layoutOverrideCoverage;
|
bool layoutOverrideCoverage;
|
||||||
bool geoPassthroughEXT;
|
bool geoPassthroughEXT;
|
||||||
|
int numShaderRecordNVBlocks;
|
||||||
|
ComputeDerivativeMode computeDerivativeMode;
|
||||||
|
int primitives;
|
||||||
|
int numTaskNVBlocks;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Base shift values
|
// Base shift values
|
||||||
std::array<unsigned int, EResCount> shiftBinding;
|
std::array<unsigned int, EResCount> shiftBinding;
|
||||||
|
|
||||||
// Per-descriptor-set shift values
|
// Per-descriptor-set shift values
|
||||||
std::array<std::map<int, int>, EResCount> shiftBindingForSet;
|
std::array<std::map<int, int>, EResCount> shiftBindingForSet;
|
||||||
|
|
||||||
std::vector<std::string> resourceSetBinding;
|
std::vector<std::string> resourceSetBinding;
|
||||||
bool autoMapBindings;
|
bool autoMapBindings;
|
||||||
|
@ -724,15 +850,12 @@ protected:
|
||||||
bool useUnknownFormat;
|
bool useUnknownFormat;
|
||||||
bool hlslOffsets;
|
bool hlslOffsets;
|
||||||
bool useStorageBuffer;
|
bool useStorageBuffer;
|
||||||
|
bool useVulkanMemoryModel;
|
||||||
bool hlslIoMapping;
|
bool hlslIoMapping;
|
||||||
|
|
||||||
typedef std::list<TCall> TGraph;
|
|
||||||
TGraph callGraph;
|
|
||||||
|
|
||||||
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
|
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
|
||||||
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
|
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
|
||||||
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
||||||
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
|
||||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||||
std::set<TString> semanticNameSet;
|
std::set<TString> semanticNameSet;
|
||||||
|
|
||||||
|
@ -742,11 +865,18 @@ protected:
|
||||||
std::string sourceFile;
|
std::string sourceFile;
|
||||||
std::string sourceText;
|
std::string sourceText;
|
||||||
|
|
||||||
|
// Included text. First string is a name, second is the included text
|
||||||
|
std::map<std::string, std::string> includeText;
|
||||||
|
|
||||||
// for OpModuleProcessed, or equivalent
|
// for OpModuleProcessed, or equivalent
|
||||||
TProcesses processes;
|
TProcesses processes;
|
||||||
|
|
||||||
bool needToLegalize;
|
bool needToLegalize;
|
||||||
bool binaryDoubleOutput;
|
bool binaryDoubleOutput;
|
||||||
|
bool usePhysicalStorageBuffer;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, int> uniformLocationOverrides;
|
||||||
|
int uniformLocationBase;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=(TIntermediate&); // prevent assignments
|
void operator=(TIntermediate&); // prevent assignments
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2016 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
@ -103,6 +103,7 @@ public:
|
||||||
virtual void requireSpv(const TSourceLoc&, const char* op);
|
virtual void requireSpv(const TSourceLoc&, const char* op);
|
||||||
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
|
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
|
||||||
|
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
|
||||||
|
|
||||||
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...) = 0;
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
|
@ -129,6 +130,7 @@ public:
|
||||||
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
||||||
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
|
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
|
||||||
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
|
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
|
||||||
|
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
|
||||||
|
|
||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
|
|
||||||
|
|
35
glslang/glslang/MachineIndependent/pch.cpp
Normal file
35
glslang/glslang/MachineIndependent/pch.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 The Khronos Group 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 "pch.h"
|
49
glslang/glslang/MachineIndependent/pch.h
Normal file
49
glslang/glslang/MachineIndependent/pch.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef _PCH_H
|
||||||
|
#define _PCH_H
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 The Khronos Group 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 <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cctype>
|
||||||
|
#include <climits>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <memory>
|
||||||
|
#include "SymbolTable.h"
|
||||||
|
#include "ParseHelper.h"
|
||||||
|
#include "Scan.h"
|
||||||
|
#include "ScanContext.h"
|
||||||
|
|
||||||
|
#endif /* _PCH_H */
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -109,11 +110,12 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
|
|
||||||
// save the macro name
|
// save the macro name
|
||||||
const int defAtom = atomStrings.getAddAtom(ppToken->name);
|
const int defAtom = atomStrings.getAddAtom(ppToken->name);
|
||||||
|
TSourceLoc defineLoc = ppToken->loc; // because ppToken might go to the next line before we report errors
|
||||||
|
|
||||||
// gather parameters to the macro, between (...)
|
// gather parameters to the macro, between (...)
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token == '(' && ! ppToken->space) {
|
if (token == '(' && !ppToken->space) {
|
||||||
mac.emptyArgs = 1;
|
mac.functionLike = 1;
|
||||||
do {
|
do {
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (mac.args.size() == 0 && token == ')')
|
if (mac.args.size() == 0 && token == ')')
|
||||||
|
@ -123,7 +125,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
mac.emptyArgs = 0;
|
|
||||||
const int argAtom = atomStrings.getAddAtom(ppToken->name);
|
const int argAtom = atomStrings.getAddAtom(ppToken->name);
|
||||||
|
|
||||||
// check for duplication of parameter name
|
// check for duplication of parameter name
|
||||||
|
@ -149,7 +150,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
// record the definition of the macro
|
// record the definition of the macro
|
||||||
TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
|
|
||||||
while (token != '\n' && token != EndOfInput) {
|
while (token != '\n' && token != EndOfInput) {
|
||||||
mac.body.putToken(token, ppToken);
|
mac.body.putToken(token, ppToken);
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
|
@ -164,7 +164,9 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
// Already defined -- need to make sure they are identical:
|
// Already defined -- need to make sure they are identical:
|
||||||
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
|
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
|
||||||
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
|
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
|
||||||
if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs)
|
if (existing->functionLike != mac.functionLike)
|
||||||
|
parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", atomStrings.getString(defAtom));
|
||||||
|
else if (existing->args.size() != mac.args.size())
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
|
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
|
||||||
else {
|
else {
|
||||||
if (existing->args != mac.args)
|
if (existing->args != mac.args)
|
||||||
|
@ -651,6 +653,7 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
||||||
epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") <<
|
epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") <<
|
||||||
"#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
|
"#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
|
||||||
pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
|
pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
|
||||||
|
parseContext.intermediate.addIncludeText(res->headerName.c_str(), res->headerData, res->headerLength);
|
||||||
// There's no "current" location anymore.
|
// There's no "current" location anymore.
|
||||||
parseContext.setCurrentColumn(0);
|
parseContext.setCurrentColumn(0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1120,7 +1123,8 @@ int TPpContext::tZeroInput::scan(TPpToken* ppToken)
|
||||||
if (done)
|
if (done)
|
||||||
return EndOfInput;
|
return EndOfInput;
|
||||||
|
|
||||||
strcpy(ppToken->name, "0");
|
ppToken->name[0] = '0';
|
||||||
|
ppToken->name[1] = 0;
|
||||||
ppToken->ival = 0;
|
ppToken->ival = 0;
|
||||||
ppToken->space = false;
|
ppToken->space = false;
|
||||||
done = true;
|
done = true;
|
||||||
|
@ -1190,14 +1194,20 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b
|
||||||
|
|
||||||
TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
|
TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
|
||||||
in->mac = macro;
|
in->mac = macro;
|
||||||
if (macro->args.size() > 0 || macro->emptyArgs) {
|
if (macro->functionLike) {
|
||||||
int token = scanToken(ppToken);
|
// We don't know yet if this will be a successful call of a
|
||||||
|
// function-like macro; need to look for a '(', but without trashing
|
||||||
|
// the passed in ppToken, until we know we are no longer speculative.
|
||||||
|
TPpToken parenToken;
|
||||||
|
int token = scanToken(&parenToken);
|
||||||
if (newLineOkay) {
|
if (newLineOkay) {
|
||||||
while (token == '\n')
|
while (token == '\n')
|
||||||
token = scanToken(ppToken);
|
token = scanToken(&parenToken);
|
||||||
}
|
}
|
||||||
if (token != '(') {
|
if (token != '(') {
|
||||||
UngetToken(token, ppToken);
|
// Function-like macro called with object-like syntax: okay, don't expand.
|
||||||
|
// (We ate exactly one token that might not be white space; put it back.
|
||||||
|
UngetToken(token, &parenToken);
|
||||||
delete in;
|
delete in;
|
||||||
return MacroExpandNotStarted;
|
return MacroExpandNotStarted;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -267,12 +268,12 @@ public:
|
||||||
//
|
//
|
||||||
|
|
||||||
struct MacroSymbol {
|
struct MacroSymbol {
|
||||||
MacroSymbol() : emptyArgs(0), busy(0), undef(0) { }
|
MacroSymbol() : functionLike(0), busy(0), undef(0) { }
|
||||||
TVector<int> args;
|
TVector<int> args;
|
||||||
TokenStream body;
|
TokenStream body;
|
||||||
unsigned emptyArgs : 1;
|
unsigned functionLike : 1; // 0 means object-like, 1 means function-like
|
||||||
unsigned busy : 1;
|
unsigned busy : 1;
|
||||||
unsigned undef : 1;
|
unsigned undef : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TMap<int, MacroSymbol> TSymbolMap;
|
typedef TMap<int, MacroSymbol> TSymbolMap;
|
||||||
|
@ -533,7 +534,7 @@ protected:
|
||||||
prologue_(prologue),
|
prologue_(prologue),
|
||||||
epilogue_(epilogue),
|
epilogue_(epilogue),
|
||||||
includedFile_(includedFile),
|
includedFile_(includedFile),
|
||||||
scanner(3, strings, lengths, names, 0, 0, true),
|
scanner(3, strings, lengths, nullptr, 0, 0, true),
|
||||||
prevScanner(nullptr),
|
prevScanner(nullptr),
|
||||||
stringInput(pp, scanner)
|
stringInput(pp, scanner)
|
||||||
{
|
{
|
||||||
|
@ -548,9 +549,9 @@ protected:
|
||||||
scanner.setLine(startLoc.line);
|
scanner.setLine(startLoc.line);
|
||||||
scanner.setString(startLoc.string);
|
scanner.setString(startLoc.string);
|
||||||
|
|
||||||
scanner.setFile(startLoc.name, 0);
|
scanner.setFile(startLoc.getFilenameStr(), 0);
|
||||||
scanner.setFile(startLoc.name, 1);
|
scanner.setFile(startLoc.getFilenameStr(), 1);
|
||||||
scanner.setFile(startLoc.name, 2);
|
scanner.setFile(startLoc.getFilenameStr(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tInput methods:
|
// tInput methods:
|
||||||
|
@ -590,8 +591,6 @@ protected:
|
||||||
const char* strings[3];
|
const char* strings[3];
|
||||||
// Length of str_, passed to scanner constructor.
|
// Length of str_, passed to scanner constructor.
|
||||||
size_t lengths[3];
|
size_t lengths[3];
|
||||||
// String names
|
|
||||||
const char* names[3];
|
|
||||||
// Scans over str_.
|
// Scans over str_.
|
||||||
TInputScanner scanner;
|
TInputScanner scanner;
|
||||||
// The previous effective scanner before the scanner in this instance
|
// The previous effective scanner before the scanner in this instance
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -316,16 +318,32 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
||||||
ppToken->dval = (double)wholeNumber * exponentValue;
|
ppToken->dval = (double)wholeNumber * exponentValue;
|
||||||
} else {
|
} else {
|
||||||
// slow path
|
// slow path
|
||||||
|
ppToken->dval = 0.0;
|
||||||
|
|
||||||
|
// remove suffix
|
||||||
|
TString numstr(ppToken->name);
|
||||||
|
if (numstr.back() == 'f' || numstr.back() == 'F')
|
||||||
|
numstr.pop_back();
|
||||||
|
if (numstr.back() == 'h' || numstr.back() == 'H')
|
||||||
|
numstr.pop_back();
|
||||||
|
if (numstr.back() == 'l' || numstr.back() == 'L')
|
||||||
|
numstr.pop_back();
|
||||||
|
|
||||||
|
// use platform library
|
||||||
strtodStream.clear();
|
strtodStream.clear();
|
||||||
strtodStream.str(ppToken->name);
|
strtodStream.str(numstr.c_str());
|
||||||
strtodStream >> ppToken->dval;
|
strtodStream >> ppToken->dval;
|
||||||
// Assume failure combined with a large exponent was overflow, in
|
|
||||||
// an attempt to set INF. Otherwise, assume underflow, and set 0.0.
|
|
||||||
if (strtodStream.fail()) {
|
if (strtodStream.fail()) {
|
||||||
|
// Assume failure combined with a large exponent was overflow, in
|
||||||
|
// an attempt to set INF.
|
||||||
if (!negativeExponent && exponent + numWholeNumberDigits > 300)
|
if (!negativeExponent && exponent + numWholeNumberDigits > 300)
|
||||||
ppToken->i64val = 0x7ff0000000000000; // +Infinity
|
ppToken->i64val = 0x7ff0000000000000; // +Infinity
|
||||||
else
|
// Assume failure combined with a small exponent was overflow.
|
||||||
|
if (negativeExponent && exponent + numWholeNumberDigits > 300)
|
||||||
ppToken->dval = 0.0;
|
ppToken->dval = 0.0;
|
||||||
|
// Unknown reason for failure. Theory is that either
|
||||||
|
// - the 0.0 is still there, or
|
||||||
|
// - something reasonable was written that is better than 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,16 +448,16 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
||||||
|
|
||||||
static const char* const Int64_Extensions[] = {
|
static const char* const Int64_Extensions[] = {
|
||||||
E_GL_ARB_gpu_shader_int64,
|
E_GL_ARB_gpu_shader_int64,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int64 };
|
E_GL_EXT_shader_explicit_arithmetic_types_int64 };
|
||||||
static const int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]);
|
static const int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]);
|
||||||
|
|
||||||
static const char* const Int16_Extensions[] = {
|
static const char* const Int16_Extensions[] = {
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
#endif
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_KHX_shader_explicit_arithmetic_types_int16 };
|
E_GL_EXT_shader_explicit_arithmetic_types_int16 };
|
||||||
static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]);
|
static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]);
|
||||||
|
|
||||||
ppToken->ival = 0;
|
ppToken->ival = 0;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -105,14 +105,29 @@ public:
|
||||||
const TString &name = base.getName();
|
const TString &name = base.getName();
|
||||||
const TType &type = base.getType();
|
const TType &type = base.getType();
|
||||||
|
|
||||||
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name);
|
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
||||||
if (it == reflection.nameToIndex.end()) {
|
if (it == reflection.nameToIndex.end()) {
|
||||||
reflection.nameToIndex[name] = (int)reflection.indexToAttribute.size();
|
reflection.nameToIndex[name.c_str()] = (int)reflection.indexToAttribute.size();
|
||||||
reflection.indexToAttribute.push_back(TObjectReflection(name, type, 0, mapToGlType(type), 0, 0));
|
reflection.indexToAttribute.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shared calculation by getOffset and getOffsets
|
||||||
|
void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize)
|
||||||
|
{
|
||||||
|
int dummyStride;
|
||||||
|
|
||||||
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
|
TLayoutMatrix subMatrixLayout = memberType.getQualifier().layoutMatrix;
|
||||||
|
int memberAlignment = intermediate.getMemberAlignment(memberType, memberSize, dummyStride,
|
||||||
|
parentType.getQualifier().layoutPacking,
|
||||||
|
subMatrixLayout != ElmNone
|
||||||
|
? subMatrixLayout == ElmRowMajor
|
||||||
|
: parentType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
|
RoundToPow2(offset, memberAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
// Lookup or calculate the offset of a block member, using the recursively
|
// Lookup or calculate the offset of a block member, using the recursively
|
||||||
// defined block offset rules.
|
// defined block offset rules.
|
||||||
int getOffset(const TType& type, int index)
|
int getOffset(const TType& type, int index)
|
||||||
|
@ -125,18 +140,11 @@ public:
|
||||||
if (memberList[index].type->getQualifier().hasOffset())
|
if (memberList[index].type->getQualifier().hasOffset())
|
||||||
return memberList[index].type->getQualifier().layoutOffset;
|
return memberList[index].type->getQualifier().layoutOffset;
|
||||||
|
|
||||||
int memberSize;
|
int memberSize = 0;
|
||||||
int dummyStride;
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (int m = 0; m <= index; ++m) {
|
for (int m = 0; m <= index; ++m) {
|
||||||
// modify just the children's view of matrix layout, if there is one for this member
|
updateOffset(type, *memberList[m].type, offset, memberSize);
|
||||||
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
|
||||||
int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, dummyStride,
|
|
||||||
type.getQualifier().layoutPacking == ElpStd140,
|
|
||||||
subMatrixLayout != ElmNone
|
|
||||||
? subMatrixLayout == ElmRowMajor
|
|
||||||
: type.getQualifier().layoutMatrix == ElmRowMajor);
|
|
||||||
RoundToPow2(offset, memberAlignment);
|
|
||||||
if (m < index)
|
if (m < index)
|
||||||
offset += memberSize;
|
offset += memberSize;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +152,50 @@ public:
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lookup or calculate the offset of all block members at once, using the recursively
|
||||||
|
// defined block offset rules.
|
||||||
|
void getOffsets(const TType& type, TVector<int>& offsets)
|
||||||
|
{
|
||||||
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
|
int memberSize = 0;
|
||||||
|
int offset = 0;
|
||||||
|
for (size_t m = 0; m < offsets.size(); ++m) {
|
||||||
|
// if the user supplied an offset, snap to it now
|
||||||
|
if (memberList[m].type->getQualifier().hasOffset())
|
||||||
|
offset = memberList[m].type->getQualifier().layoutOffset;
|
||||||
|
|
||||||
|
// calculate the offset of the next member and align the current offset to this member
|
||||||
|
updateOffset(type, *memberList[m].type, offset, memberSize);
|
||||||
|
|
||||||
|
// save the offset of this member
|
||||||
|
offsets[m] = offset;
|
||||||
|
|
||||||
|
// update for the next member
|
||||||
|
offset += memberSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the stride of an array type
|
||||||
|
int getArrayStride(const TType& baseType, const TType& type)
|
||||||
|
{
|
||||||
|
int dummySize;
|
||||||
|
int stride;
|
||||||
|
|
||||||
|
// consider blocks to have 0 stride, so that all offsets are relative to the start of their block
|
||||||
|
if (type.getBasicType() == EbtBlock)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
TLayoutMatrix subMatrixLayout = type.getQualifier().layoutMatrix;
|
||||||
|
intermediate.getMemberAlignment(type, dummySize, stride,
|
||||||
|
baseType.getQualifier().layoutPacking,
|
||||||
|
subMatrixLayout != ElmNone
|
||||||
|
? subMatrixLayout == ElmRowMajor
|
||||||
|
: baseType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
|
|
||||||
|
return stride;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the block data size.
|
// Calculate the block data size.
|
||||||
// Block arrayness is not taken into account, each element is backed by a separate buffer.
|
// Block arrayness is not taken into account, each element is backed by a separate buffer.
|
||||||
int getBlockSize(const TType& blockType)
|
int getBlockSize(const TType& blockType)
|
||||||
|
@ -154,9 +206,9 @@ public:
|
||||||
|
|
||||||
int lastMemberSize;
|
int lastMemberSize;
|
||||||
int dummyStride;
|
int dummyStride;
|
||||||
intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride,
|
intermediate.getMemberAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride,
|
||||||
blockType.getQualifier().layoutPacking == ElpStd140,
|
blockType.getQualifier().layoutPacking,
|
||||||
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
|
|
||||||
return lastOffset + lastMemberSize;
|
return lastOffset + lastMemberSize;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +231,9 @@ public:
|
||||||
terminalType = &visitNode->getType();
|
terminalType = &visitNode->getType();
|
||||||
int index;
|
int index;
|
||||||
switch (visitNode->getOp()) {
|
switch (visitNode->getOp()) {
|
||||||
case EOpIndexIndirect:
|
case EOpIndexIndirect: {
|
||||||
|
int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
|
||||||
|
|
||||||
// Visit all the indices of this array, and for each one add on the remaining dereferencing
|
// Visit all the indices of this array, and for each one add on the remaining dereferencing
|
||||||
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
|
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
|
||||||
TString newBaseName = name;
|
TString newBaseName = name;
|
||||||
|
@ -189,14 +243,22 @@ public:
|
||||||
++nextDeref;
|
++nextDeref;
|
||||||
TType derefType(*terminalType, 0);
|
TType derefType(*terminalType, 0);
|
||||||
blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize);
|
blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize);
|
||||||
|
|
||||||
|
if (offset >= 0)
|
||||||
|
offset += stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
// it was all completed in the recursive calls above
|
// it was all completed in the recursive calls above
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
case EOpIndexDirect:
|
case EOpIndexDirect:
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (baseType.getBasicType() != EbtBlock)
|
if (baseType.getBasicType() != EbtBlock) {
|
||||||
name.append(TString("[") + String(index) + "]");
|
name.append(TString("[") + String(index) + "]");
|
||||||
|
|
||||||
|
if (offset >= 0)
|
||||||
|
offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
@ -213,23 +275,43 @@ public:
|
||||||
|
|
||||||
// if the terminalType is still too coarse a granularity, this is still an aggregate to expand, expand it...
|
// if the terminalType is still too coarse a granularity, this is still an aggregate to expand, expand it...
|
||||||
if (! isReflectionGranularity(*terminalType)) {
|
if (! isReflectionGranularity(*terminalType)) {
|
||||||
|
// the base offset of this node, that children are relative to
|
||||||
|
int baseOffset = offset;
|
||||||
|
|
||||||
if (terminalType->isArray()) {
|
if (terminalType->isArray()) {
|
||||||
// Visit all the indices of this array, and for each one,
|
// Visit all the indices of this array, and for each one,
|
||||||
// fully explode the remaining aggregate to dereference
|
// fully explode the remaining aggregate to dereference
|
||||||
|
|
||||||
|
int stride = 0;
|
||||||
|
if (offset >= 0)
|
||||||
|
stride = getArrayStride(baseType, *terminalType);
|
||||||
|
|
||||||
for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) {
|
for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) {
|
||||||
TString newBaseName = name;
|
TString newBaseName = name;
|
||||||
newBaseName.append(TString("[") + String(i) + "]");
|
newBaseName.append(TString("[") + String(i) + "]");
|
||||||
TType derefType(*terminalType, 0);
|
TType derefType(*terminalType, 0);
|
||||||
|
if (offset >= 0)
|
||||||
|
offset = baseOffset + stride * i;
|
||||||
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
|
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Visit all members of this aggregate, and for each one,
|
// Visit all members of this aggregate, and for each one,
|
||||||
// fully explode the remaining aggregate to dereference
|
// fully explode the remaining aggregate to dereference
|
||||||
const TTypeList& typeList = *terminalType->getStruct();
|
const TTypeList& typeList = *terminalType->getStruct();
|
||||||
|
|
||||||
|
TVector<int> memberOffsets;
|
||||||
|
|
||||||
|
if (baseOffset >= 0) {
|
||||||
|
memberOffsets.resize(typeList.size());
|
||||||
|
getOffsets(*terminalType, memberOffsets);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (int)typeList.size(); ++i) {
|
for (int i = 0; i < (int)typeList.size(); ++i) {
|
||||||
TString newBaseName = name;
|
TString newBaseName = name;
|
||||||
newBaseName.append(TString(".") + typeList[i].type->getFieldName());
|
newBaseName.append(TString(".") + typeList[i].type->getFieldName());
|
||||||
TType derefType(*terminalType, i);
|
TType derefType(*terminalType, i);
|
||||||
|
if (offset >= 0)
|
||||||
|
offset = baseOffset + memberOffsets[i];
|
||||||
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
|
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,10 +327,10 @@ public:
|
||||||
if (arraySize == 0)
|
if (arraySize == 0)
|
||||||
arraySize = mapToGlArraySize(*terminalType);
|
arraySize = mapToGlArraySize(*terminalType);
|
||||||
|
|
||||||
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name);
|
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
||||||
if (it == reflection.nameToIndex.end()) {
|
if (it == reflection.nameToIndex.end()) {
|
||||||
reflection.nameToIndex[name] = (int)reflection.indexToUniform.size();
|
reflection.nameToIndex[name.c_str()] = (int)reflection.indexToUniform.size();
|
||||||
reflection.indexToUniform.push_back(TObjectReflection(name, *terminalType, offset,
|
reflection.indexToUniform.push_back(TObjectReflection(name.c_str(), *terminalType, offset,
|
||||||
mapToGlType(*terminalType),
|
mapToGlType(*terminalType),
|
||||||
arraySize, blockIndex));
|
arraySize, blockIndex));
|
||||||
} else if (arraySize > 1) {
|
} else if (arraySize > 1) {
|
||||||
|
@ -348,11 +430,11 @@ public:
|
||||||
int addBlockName(const TString& name, const TType& type, int size)
|
int addBlockName(const TString& name, const TType& type, int size)
|
||||||
{
|
{
|
||||||
int blockIndex;
|
int blockIndex;
|
||||||
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name);
|
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
||||||
if (reflection.nameToIndex.find(name) == reflection.nameToIndex.end()) {
|
if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
|
||||||
blockIndex = (int)reflection.indexToUniformBlock.size();
|
blockIndex = (int)reflection.indexToUniformBlock.size();
|
||||||
reflection.nameToIndex[name] = blockIndex;
|
reflection.nameToIndex[name.c_str()] = blockIndex;
|
||||||
reflection.indexToUniformBlock.push_back(TObjectReflection(name, type, -1, -1, size, -1));
|
reflection.indexToUniformBlock.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
|
||||||
} else
|
} else
|
||||||
blockIndex = it->second;
|
blockIndex = it->second;
|
||||||
|
|
||||||
|
@ -770,7 +852,7 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
||||||
{
|
{
|
||||||
// search for ones that have counters
|
// search for ones that have counters
|
||||||
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
||||||
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name));
|
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str());
|
||||||
const int index = getIndex(counterName);
|
const int index = getIndex(counterName);
|
||||||
|
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
|
|
|
@ -55,11 +55,11 @@ class TReflectionTraverser;
|
||||||
// Data needed for just a single object at the granularity exchanged by the reflection API
|
// Data needed for just a single object at the granularity exchanged by the reflection API
|
||||||
class TObjectReflection {
|
class TObjectReflection {
|
||||||
public:
|
public:
|
||||||
TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
|
TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
|
||||||
name(pName), offset(pOffset),
|
name(pName), offset(pOffset),
|
||||||
glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), type(pType.clone()), stages(EShLanguageMask(0)) { }
|
glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), stages(EShLanguageMask(0)), type(pType.clone()) { }
|
||||||
|
|
||||||
const TType* const getType() const { return type; }
|
const TType* getType() const { return type; }
|
||||||
int getBinding() const
|
int getBinding() const
|
||||||
{
|
{
|
||||||
if (type == nullptr || !type->getQualifier().hasBinding())
|
if (type == nullptr || !type->getQualifier().hasBinding())
|
||||||
|
@ -78,7 +78,7 @@ public:
|
||||||
}
|
}
|
||||||
static TObjectReflection badReflection() { return TObjectReflection(); }
|
static TObjectReflection badReflection() { return TObjectReflection(); }
|
||||||
|
|
||||||
TString name;
|
std::string name;
|
||||||
int offset;
|
int offset;
|
||||||
int glDefineType;
|
int glDefineType;
|
||||||
int size; // data size in bytes for a block, array size for a (non-block) object that's an array
|
int size; // data size in bytes for a block, array size for a (non-block) object that's an array
|
||||||
|
@ -87,7 +87,8 @@ public:
|
||||||
EShLanguageMask stages;
|
EShLanguageMask stages;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TObjectReflection() : offset(-1), glDefineType(-1), size(-1), index(-1), type(nullptr) { }
|
TObjectReflection() :
|
||||||
|
offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), stages(EShLanguageMask(0)), type(nullptr) { }
|
||||||
|
|
||||||
const TType* type;
|
const TType* type;
|
||||||
};
|
};
|
||||||
|
@ -162,7 +163,7 @@ protected:
|
||||||
void buildAttributeReflection(EShLanguage, const TIntermediate&);
|
void buildAttributeReflection(EShLanguage, const TIntermediate&);
|
||||||
|
|
||||||
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
||||||
typedef std::map<TString, int> TNameToIndex;
|
typedef std::map<std::string, int> TNameToIndex;
|
||||||
typedef std::vector<TObjectReflection> TMapIndexToReflection;
|
typedef std::vector<TObjectReflection> TMapIndexToReflection;
|
||||||
|
|
||||||
TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
|
TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
|
||||||
|
|
|
@ -2,6 +2,23 @@ add_library(OSDependent STATIC ossource.cpp ../osinclude.h)
|
||||||
set_property(TARGET OSDependent PROPERTY FOLDER glslang)
|
set_property(TARGET OSDependent PROPERTY FOLDER glslang)
|
||||||
set_property(TARGET OSDependent PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET OSDependent PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
# Link pthread
|
||||||
|
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS "3.1.0" OR CMAKE_CROSSCOMPILING)
|
||||||
|
# Needed as long as we support CMake 2.8 for Ubuntu 14.04,
|
||||||
|
# which does not support the recommended Threads::Threads target.
|
||||||
|
# https://cmake.org/cmake/help/v2.8.12/cmake.html#module:FindThreads
|
||||||
|
# Also needed when cross-compiling to work around
|
||||||
|
# https://gitlab.kitware.com/cmake/cmake/issues/16920
|
||||||
|
find_package(Threads)
|
||||||
|
target_link_libraries(OSDependent ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
else()
|
||||||
|
# This is the recommended way, so we use it for 3.1+.
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads)
|
||||||
|
target_link_libraries(OSDependent Threads::Threads)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ENABLE_GLSLANG_INSTALL)
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
install(TARGETS OSDependent
|
install(TARGETS OSDependent
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
|
|
@ -45,7 +45,10 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#if !defined(__Fuchsia__)
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
@ -70,7 +73,7 @@ static void DetachThreadLinux(void *)
|
||||||
//
|
//
|
||||||
void OS_CleanupThreadData(void)
|
void OS_CleanupThreadData(void)
|
||||||
{
|
{
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__Fuchsia__)
|
||||||
DetachThreadLinux(NULL);
|
DetachThreadLinux(NULL);
|
||||||
#else
|
#else
|
||||||
int old_cancel_state, old_cancel_type;
|
int old_cancel_state, old_cancel_type;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013-2016 LunarG, Inc.
|
// Copyright (C) 2013-2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -52,9 +53,6 @@
|
||||||
#define SH_IMPORT_EXPORT
|
#define SH_IMPORT_EXPORT
|
||||||
#else
|
#else
|
||||||
#define SH_IMPORT_EXPORT
|
#define SH_IMPORT_EXPORT
|
||||||
#ifndef __fastcall
|
|
||||||
#define __fastcall
|
|
||||||
#endif
|
|
||||||
#define C_DECL
|
#define C_DECL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@
|
||||||
// This should always increase, as some paths to do not consume
|
// This should always increase, as some paths to do not consume
|
||||||
// a more major number.
|
// a more major number.
|
||||||
// It should increment by one when new functionality is added.
|
// It should increment by one when new functionality is added.
|
||||||
#define GLSLANG_MINOR_VERSION 8
|
#define GLSLANG_MINOR_VERSION 11
|
||||||
|
|
||||||
//
|
//
|
||||||
// Call before doing any other compiler/linker operations.
|
// Call before doing any other compiler/linker operations.
|
||||||
|
@ -82,7 +80,7 @@ SH_IMPORT_EXPORT int ShInitialize();
|
||||||
//
|
//
|
||||||
// Call this at process shutdown to clean up memory.
|
// Call this at process shutdown to clean up memory.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT int __fastcall ShFinalize();
|
SH_IMPORT_EXPORT int ShFinalize();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Types of languages the compiler can consume.
|
// Types of languages the compiler can consume.
|
||||||
|
@ -94,6 +92,14 @@ typedef enum {
|
||||||
EShLangGeometry,
|
EShLangGeometry,
|
||||||
EShLangFragment,
|
EShLangFragment,
|
||||||
EShLangCompute,
|
EShLangCompute,
|
||||||
|
EShLangRayGenNV,
|
||||||
|
EShLangIntersectNV,
|
||||||
|
EShLangAnyHitNV,
|
||||||
|
EShLangClosestHitNV,
|
||||||
|
EShLangMissNV,
|
||||||
|
EShLangCallableNV,
|
||||||
|
EShLangTaskNV,
|
||||||
|
EShLangMeshNV,
|
||||||
EShLangCount,
|
EShLangCount,
|
||||||
} EShLanguage; // would be better as stage, but this is ancient now
|
} EShLanguage; // would be better as stage, but this is ancient now
|
||||||
|
|
||||||
|
@ -104,6 +110,14 @@ typedef enum {
|
||||||
EShLangGeometryMask = (1 << EShLangGeometry),
|
EShLangGeometryMask = (1 << EShLangGeometry),
|
||||||
EShLangFragmentMask = (1 << EShLangFragment),
|
EShLangFragmentMask = (1 << EShLangFragment),
|
||||||
EShLangComputeMask = (1 << EShLangCompute),
|
EShLangComputeMask = (1 << EShLangCompute),
|
||||||
|
EShLangRayGenNVMask = (1 << EShLangRayGenNV),
|
||||||
|
EShLangIntersectNVMask = (1 << EShLangIntersectNV),
|
||||||
|
EShLangAnyHitNVMask = (1 << EShLangAnyHitNV),
|
||||||
|
EShLangClosestHitNVMask = (1 << EShLangClosestHitNV),
|
||||||
|
EShLangMissNVMask = (1 << EShLangMissNV),
|
||||||
|
EShLangCallableNVMask = (1 << EShLangCallableNV),
|
||||||
|
EShLangTaskNVMask = (1 << EShLangTaskNV),
|
||||||
|
EShLangMeshNVMask = (1 << EShLangMeshNV),
|
||||||
} EShLanguageMask;
|
} EShLanguageMask;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
@ -138,7 +152,10 @@ typedef EShTargetClientVersion EshTargetClientVersion;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetSpv_1_0 = (1 << 16),
|
EShTargetSpv_1_0 = (1 << 16),
|
||||||
|
EShTargetSpv_1_1 = (1 << 16) | (1 << 8),
|
||||||
|
EShTargetSpv_1_2 = (1 << 16) | (2 << 8),
|
||||||
EShTargetSpv_1_3 = (1 << 16) | (3 << 8),
|
EShTargetSpv_1_3 = (1 << 16) | (3 << 8),
|
||||||
|
EShTargetSpv_1_4 = (1 << 16) | (4 << 8),
|
||||||
} EShTargetLanguageVersion;
|
} EShTargetLanguageVersion;
|
||||||
|
|
||||||
struct TInputLanguage {
|
struct TInputLanguage {
|
||||||
|
@ -216,6 +233,7 @@ enum EShMessages {
|
||||||
EShMsgDebugInfo = (1 << 10), // save debug information
|
EShMsgDebugInfo = (1 << 10), // save debug information
|
||||||
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
|
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
|
||||||
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
|
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
|
||||||
|
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -397,6 +415,8 @@ public:
|
||||||
void setResourceSetBinding(const std::vector<std::string>& base);
|
void setResourceSetBinding(const std::vector<std::string>& base);
|
||||||
void setAutoMapBindings(bool map);
|
void setAutoMapBindings(bool map);
|
||||||
void setAutoMapLocations(bool map);
|
void setAutoMapLocations(bool map);
|
||||||
|
void addUniformLocationOverride(const char* name, int loc);
|
||||||
|
void setUniformLocationBase(int base);
|
||||||
void setInvertY(bool invert);
|
void setInvertY(bool invert);
|
||||||
void setHlslIoMapping(bool hlslIoMap);
|
void setHlslIoMapping(bool hlslIoMap);
|
||||||
void setFlattenUniformArrays(bool flatten);
|
void setFlattenUniformArrays(bool flatten);
|
||||||
|
@ -532,6 +552,8 @@ public:
|
||||||
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
|
return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
|
||||||
|
// is not an officially supported or fully working path.
|
||||||
bool preprocess(const TBuiltInResource* builtInResources,
|
bool preprocess(const TBuiltInResource* builtInResources,
|
||||||
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
bool forwardCompatible, EShMessages message, std::string* outputString,
|
bool forwardCompatible, EShMessages message, std::string* outputString,
|
||||||
|
|
|
@ -19,7 +19,9 @@ set(SOURCES
|
||||||
InReadableOrder.cpp
|
InReadableOrder.cpp
|
||||||
Logger.cpp
|
Logger.cpp
|
||||||
SpvBuilder.cpp
|
SpvBuilder.cpp
|
||||||
|
SpvPostProcess.cpp
|
||||||
doc.cpp
|
doc.cpp
|
||||||
|
SpvTools.cpp
|
||||||
disassemble.cpp)
|
disassemble.cpp)
|
||||||
|
|
||||||
set(SPVREMAP_SOURCES
|
set(SPVREMAP_SOURCES
|
||||||
|
@ -38,6 +40,7 @@ set(HEADERS
|
||||||
SpvBuilder.h
|
SpvBuilder.h
|
||||||
spvIR.h
|
spvIR.h
|
||||||
doc.h
|
doc.h
|
||||||
|
SpvTools.h
|
||||||
disassemble.h)
|
disassemble.h)
|
||||||
|
|
||||||
set(SPVREMAP_HEADERS
|
set(SPVREMAP_HEADERS
|
||||||
|
@ -61,13 +64,17 @@ set_property(TARGET SPIRV PROPERTY FOLDER glslang)
|
||||||
set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
target_include_directories(SPIRV PUBLIC ..)
|
target_include_directories(SPIRV PUBLIC ..)
|
||||||
|
|
||||||
add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
if (ENABLE_SPVREMAPPER)
|
||||||
set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
|
add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||||
set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
|
||||||
|
set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||||
set_target_properties(SPIRV PROPERTIES PREFIX "")
|
set_target_properties(SPIRV PROPERTIES PREFIX "")
|
||||||
set_target_properties(SPVRemapper PROPERTIES PREFIX "")
|
if (ENABLE_SPVREMAPPER)
|
||||||
|
set_target_properties(SPVRemapper PROPERTIES PREFIX "")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_OPT)
|
if(ENABLE_OPT)
|
||||||
|
@ -88,11 +95,20 @@ endif(WIN32)
|
||||||
|
|
||||||
if(ENABLE_GLSLANG_INSTALL)
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
if(BUILD_SHARED_LIBS)
|
if(BUILD_SHARED_LIBS)
|
||||||
install(TARGETS SPIRV SPVRemapper
|
if (ENABLE_SPVREMAPPER)
|
||||||
|
install(TARGETS SPVRemapper
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif()
|
||||||
|
install(TARGETS SPIRV
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
else()
|
else()
|
||||||
install(TARGETS SPIRV SPVRemapper
|
if (ENABLE_SPVREMAPPER)
|
||||||
|
install(TARGETS SPVRemapper
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif()
|
||||||
|
install(TARGETS SPIRV
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,11 @@
|
||||||
#define GLSLextEXT_H
|
#define GLSLextEXT_H
|
||||||
|
|
||||||
static const int GLSLextEXTVersion = 100;
|
static const int GLSLextEXTVersion = 100;
|
||||||
static const int GLSLextEXTRevision = 1;
|
static const int GLSLextEXTRevision = 2;
|
||||||
|
|
||||||
static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shader_stencil_export";
|
static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shader_stencil_export";
|
||||||
static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer";
|
static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer";
|
||||||
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
|
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
|
||||||
|
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
|
||||||
|
|
||||||
#endif // #ifndef GLSLextEXT_H
|
#endif // #ifndef GLSLextEXT_H
|
||||||
|
|
|
@ -39,5 +39,7 @@ static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit
|
||||||
static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_storage";
|
static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_storage";
|
||||||
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
|
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
|
||||||
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
|
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
|
||||||
|
static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model";
|
||||||
|
static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physical_storage_buffer";
|
||||||
|
|
||||||
#endif // #ifndef GLSLextKHR_H
|
#endif // #ifndef GLSLextKHR_H
|
||||||
|
|
|
@ -33,7 +33,7 @@ enum Op;
|
||||||
enum Capability;
|
enum Capability;
|
||||||
|
|
||||||
static const int GLSLextNVVersion = 100;
|
static const int GLSLextNVVersion = 100;
|
||||||
static const int GLSLextNVRevision = 5;
|
static const int GLSLextNVRevision = 11;
|
||||||
|
|
||||||
//SPV_NV_sample_mask_override_coverage
|
//SPV_NV_sample_mask_override_coverage
|
||||||
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
||||||
|
@ -54,4 +54,22 @@ const char* const E_SPV_NVX_multiview_per_view_attributes = "SPV_NVX_multiview_p
|
||||||
//SPV_NV_shader_subgroup_partitioned
|
//SPV_NV_shader_subgroup_partitioned
|
||||||
const char* const E_SPV_NV_shader_subgroup_partitioned = "SPV_NV_shader_subgroup_partitioned";
|
const char* const E_SPV_NV_shader_subgroup_partitioned = "SPV_NV_shader_subgroup_partitioned";
|
||||||
|
|
||||||
#endif // #ifndef GLSLextNV_H
|
//SPV_NV_fragment_shader_barycentric
|
||||||
|
const char* const E_SPV_NV_fragment_shader_barycentric = "SPV_NV_fragment_shader_barycentric";
|
||||||
|
|
||||||
|
//SPV_NV_compute_shader_derivatives
|
||||||
|
const char* const E_SPV_NV_compute_shader_derivatives = "SPV_NV_compute_shader_derivatives";
|
||||||
|
|
||||||
|
//SPV_NV_shader_image_footprint
|
||||||
|
const char* const E_SPV_NV_shader_image_footprint = "SPV_NV_shader_image_footprint";
|
||||||
|
|
||||||
|
//SPV_NV_mesh_shader
|
||||||
|
const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
|
||||||
|
|
||||||
|
//SPV_NV_raytracing
|
||||||
|
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
|
||||||
|
|
||||||
|
//SPV_NV_shading_rate
|
||||||
|
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextNV_H
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014 LunarG, Inc.
|
// Copyright (C) 2014 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
#pragma warning(disable : 4464) // relative include path contains '..'
|
#pragma warning(disable : 4464) // relative include path contains '..'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "SpvTools.h"
|
||||||
#include "../glslang/Include/intermediate.h"
|
#include "../glslang/Include/intermediate.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -47,14 +49,6 @@
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
struct SpvOptions {
|
|
||||||
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
|
||||||
optimizeSize(false) { }
|
|
||||||
bool generateDebugInfo;
|
|
||||||
bool disableOptimizer;
|
|
||||||
bool optimizeSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
void GetSpirvVersion(std::string&);
|
void GetSpirvVersion(std::string&);
|
||||||
int GetSpirvGeneratorVersion();
|
int GetSpirvGeneratorVersion();
|
||||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2016 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -60,6 +60,7 @@ Builder::Builder(unsigned int spvVersion, unsigned int magicNumber, SpvBuildLogg
|
||||||
sourceVersion(0),
|
sourceVersion(0),
|
||||||
sourceFileStringId(NoResult),
|
sourceFileStringId(NoResult),
|
||||||
currentLine(0),
|
currentLine(0),
|
||||||
|
currentFile(nullptr),
|
||||||
emitOpLines(false),
|
emitOpLines(false),
|
||||||
addressModel(AddressingModelLogical),
|
addressModel(AddressingModelLogical),
|
||||||
memoryModel(MemoryModelGLSL450),
|
memoryModel(MemoryModelGLSL450),
|
||||||
|
@ -81,13 +82,15 @@ Id Builder::import(const char* name)
|
||||||
{
|
{
|
||||||
Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport);
|
Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport);
|
||||||
import->addStringOperand(name);
|
import->addStringOperand(name);
|
||||||
|
module.mapInstruction(import);
|
||||||
|
|
||||||
imports.push_back(std::unique_ptr<Instruction>(import));
|
imports.push_back(std::unique_ptr<Instruction>(import));
|
||||||
return import->getResultId();
|
return import->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit an OpLine if we've been asked to emit OpLines and the line number
|
// Emit instruction for non-filename-based #line directives (ie. no filename
|
||||||
// has changed since the last time, and is a valid line number.
|
// seen yet): emit an OpLine if we've been asked to emit OpLines and the line
|
||||||
|
// number has changed since the last time, and is a valid line number.
|
||||||
void Builder::setLine(int lineNum)
|
void Builder::setLine(int lineNum)
|
||||||
{
|
{
|
||||||
if (lineNum != 0 && lineNum != currentLine) {
|
if (lineNum != 0 && lineNum != currentLine) {
|
||||||
|
@ -97,6 +100,26 @@ void Builder::setLine(int lineNum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no filename, do non-filename-based #line emit. Else do filename-based emit.
|
||||||
|
// Emit OpLine if we've been asked to emit OpLines and the line number or filename
|
||||||
|
// has changed since the last time, and line number is valid.
|
||||||
|
void Builder::setLine(int lineNum, const char* filename)
|
||||||
|
{
|
||||||
|
if (filename == nullptr) {
|
||||||
|
setLine(lineNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((lineNum != 0 && lineNum != currentLine) || currentFile == nullptr ||
|
||||||
|
strncmp(filename, currentFile, strlen(currentFile) + 1) != 0) {
|
||||||
|
currentLine = lineNum;
|
||||||
|
currentFile = filename;
|
||||||
|
if (emitOpLines) {
|
||||||
|
spv::Id strId = getStringId(filename);
|
||||||
|
addLine(strId, currentLine, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addLine(Id fileName, int lineNum, int column)
|
void Builder::addLine(Id fileName, int lineNum, int column)
|
||||||
{
|
{
|
||||||
Instruction* line = new Instruction(OpLine);
|
Instruction* line = new Instruction(OpLine);
|
||||||
|
@ -171,6 +194,40 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id Builder::makeForwardPointer(StorageClass storageClass)
|
||||||
|
{
|
||||||
|
// Caching/uniquifying doesn't work here, because we don't know the
|
||||||
|
// pointee type and there can be multiple forward pointers of the same
|
||||||
|
// storage type. Somebody higher up in the stack must keep track.
|
||||||
|
Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeForwardPointer);
|
||||||
|
type->addImmediateOperand(storageClass);
|
||||||
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
|
module.mapInstruction(type);
|
||||||
|
|
||||||
|
return type->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
|
Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardPointerType, Id pointee)
|
||||||
|
{
|
||||||
|
// try to find it
|
||||||
|
Instruction* type;
|
||||||
|
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
||||||
|
type = groupedTypes[OpTypePointer][t];
|
||||||
|
if (type->getImmediateOperand(0) == (unsigned)storageClass &&
|
||||||
|
type->getIdOperand(1) == pointee)
|
||||||
|
return type->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
|
type = new Instruction(forwardPointerType, NoType, OpTypePointer);
|
||||||
|
type->addImmediateOperand(storageClass);
|
||||||
|
type->addIdOperand(pointee);
|
||||||
|
groupedTypes[OpTypePointer].push_back(type);
|
||||||
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
|
module.mapInstruction(type);
|
||||||
|
|
||||||
|
return type->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
Id Builder::makeIntegerType(int width, bool hasSign)
|
Id Builder::makeIntegerType(int width, bool hasSign)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
|
@ -193,10 +250,8 @@ Id Builder::makeIntegerType(int width, bool hasSign)
|
||||||
// deal with capabilities
|
// deal with capabilities
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case 8:
|
case 8:
|
||||||
addCapability(CapabilityInt8);
|
|
||||||
break;
|
|
||||||
case 16:
|
case 16:
|
||||||
addCapability(CapabilityInt16);
|
// these are currently handled by storage-type declarations and post processing
|
||||||
break;
|
break;
|
||||||
case 64:
|
case 64:
|
||||||
addCapability(CapabilityInt64);
|
addCapability(CapabilityInt64);
|
||||||
|
@ -228,7 +283,7 @@ Id Builder::makeFloatType(int width)
|
||||||
// deal with capabilities
|
// deal with capabilities
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case 16:
|
case 16:
|
||||||
addCapability(CapabilityFloat16);
|
// currently handled by storage-type declarations and post processing
|
||||||
break;
|
break;
|
||||||
case 64:
|
case 64:
|
||||||
addCapability(CapabilityFloat64);
|
addCapability(CapabilityFloat64);
|
||||||
|
@ -504,12 +559,28 @@ Id Builder::makeSampledImageType(Id imageType)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
Id Builder::makeAccelerationStructureNVType()
|
||||||
|
{
|
||||||
|
Instruction *type;
|
||||||
|
if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) {
|
||||||
|
type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV);
|
||||||
|
groupedTypes[OpTypeAccelerationStructureNV].push_back(type);
|
||||||
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
|
module.mapInstruction(type);
|
||||||
|
} else {
|
||||||
|
type = groupedTypes[OpTypeAccelerationStructureNV].back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return type->getResultId();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Id Builder::getDerefTypeId(Id resultId) const
|
Id Builder::getDerefTypeId(Id resultId) const
|
||||||
{
|
{
|
||||||
Id typeId = getTypeId(resultId);
|
Id typeId = getTypeId(resultId);
|
||||||
assert(isPointerType(typeId));
|
assert(isPointerType(typeId));
|
||||||
|
|
||||||
return module.getInstruction(typeId)->getImmediateOperand(1);
|
return module.getInstruction(typeId)->getIdOperand(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Op Builder::getMostBasicTypeClass(Id typeId) const
|
Op Builder::getMostBasicTypeClass(Id typeId) const
|
||||||
|
@ -519,12 +590,6 @@ Op Builder::getMostBasicTypeClass(Id typeId) const
|
||||||
Op typeClass = instr->getOpCode();
|
Op typeClass = instr->getOpCode();
|
||||||
switch (typeClass)
|
switch (typeClass)
|
||||||
{
|
{
|
||||||
case OpTypeVoid:
|
|
||||||
case OpTypeBool:
|
|
||||||
case OpTypeInt:
|
|
||||||
case OpTypeFloat:
|
|
||||||
case OpTypeStruct:
|
|
||||||
return typeClass;
|
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
case OpTypeArray:
|
case OpTypeArray:
|
||||||
|
@ -533,8 +598,7 @@ Op Builder::getMostBasicTypeClass(Id typeId) const
|
||||||
case OpTypePointer:
|
case OpTypePointer:
|
||||||
return getMostBasicTypeClass(instr->getIdOperand(1));
|
return getMostBasicTypeClass(instr->getIdOperand(1));
|
||||||
default:
|
default:
|
||||||
assert(0);
|
return typeClass;
|
||||||
return OpTypeFloat;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,13 +611,14 @@ int Builder::getNumTypeConstituents(Id typeId) const
|
||||||
case OpTypeBool:
|
case OpTypeBool:
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
case OpTypeFloat:
|
case OpTypeFloat:
|
||||||
|
case OpTypePointer:
|
||||||
return 1;
|
return 1;
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
return instr->getImmediateOperand(1);
|
return instr->getImmediateOperand(1);
|
||||||
case OpTypeArray:
|
case OpTypeArray:
|
||||||
{
|
{
|
||||||
Id lengthId = instr->getImmediateOperand(1);
|
Id lengthId = instr->getIdOperand(1);
|
||||||
return module.getInstruction(lengthId)->getImmediateOperand(0);
|
return module.getInstruction(lengthId)->getImmediateOperand(0);
|
||||||
}
|
}
|
||||||
case OpTypeStruct:
|
case OpTypeStruct:
|
||||||
|
@ -621,6 +686,55 @@ Id Builder::getContainedTypeId(Id typeId) const
|
||||||
return getContainedTypeId(typeId, 0);
|
return getContainedTypeId(typeId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if 'typeId' is or contains a scalar type declared with 'typeOp'
|
||||||
|
// of width 'width'. The 'width' is only consumed for int and float types.
|
||||||
|
// Returns false otherwise.
|
||||||
|
bool Builder::containsType(Id typeId, spv::Op typeOp, unsigned int width) const
|
||||||
|
{
|
||||||
|
const Instruction& instr = *module.getInstruction(typeId);
|
||||||
|
|
||||||
|
Op typeClass = instr.getOpCode();
|
||||||
|
switch (typeClass)
|
||||||
|
{
|
||||||
|
case OpTypeInt:
|
||||||
|
case OpTypeFloat:
|
||||||
|
return typeClass == typeOp && instr.getImmediateOperand(0) == width;
|
||||||
|
case OpTypeStruct:
|
||||||
|
for (int m = 0; m < instr.getNumOperands(); ++m) {
|
||||||
|
if (containsType(instr.getIdOperand(m), typeOp, width))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case OpTypePointer:
|
||||||
|
return false;
|
||||||
|
case OpTypeVector:
|
||||||
|
case OpTypeMatrix:
|
||||||
|
case OpTypeArray:
|
||||||
|
case OpTypeRuntimeArray:
|
||||||
|
return containsType(getContainedTypeId(typeId), typeOp, width);
|
||||||
|
default:
|
||||||
|
return typeClass == typeOp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return true if the type is a pointer to PhysicalStorageBufferEXT or an
|
||||||
|
// array of such pointers. These require restrict/aliased decorations.
|
||||||
|
bool Builder::containsPhysicalStorageBufferOrArray(Id typeId) const
|
||||||
|
{
|
||||||
|
const Instruction& instr = *module.getInstruction(typeId);
|
||||||
|
|
||||||
|
Op typeClass = instr.getOpCode();
|
||||||
|
switch (typeClass)
|
||||||
|
{
|
||||||
|
case OpTypePointer:
|
||||||
|
return getTypeStorageClass(typeId) == StorageClassPhysicalStorageBufferEXT;
|
||||||
|
case OpTypeArray:
|
||||||
|
return containsPhysicalStorageBufferOrArray(getContainedTypeId(typeId));
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See if a scalar constant of this type has already been created, so it
|
// See if a scalar constant of this type has already been created, so it
|
||||||
// can be reused rather than duplicated. (Required by the specification).
|
// can be reused rather than duplicated. (Required by the specification).
|
||||||
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
|
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
|
||||||
|
@ -1193,20 +1307,65 @@ Id Builder::createUndefined(Id type)
|
||||||
return inst->getResultId();
|
return inst->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// av/vis/nonprivate are unnecessary and illegal for some storage classes.
|
||||||
|
spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const
|
||||||
|
{
|
||||||
|
switch (sc) {
|
||||||
|
case spv::StorageClassUniform:
|
||||||
|
case spv::StorageClassWorkgroup:
|
||||||
|
case spv::StorageClassStorageBuffer:
|
||||||
|
case spv::StorageClassPhysicalStorageBufferEXT:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
memoryAccess = spv::MemoryAccessMask(memoryAccess &
|
||||||
|
~(spv::MemoryAccessMakePointerAvailableKHRMask |
|
||||||
|
spv::MemoryAccessMakePointerVisibleKHRMask |
|
||||||
|
spv::MemoryAccessNonPrivatePointerKHRMask));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return memoryAccess;
|
||||||
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::createStore(Id rValue, Id lValue)
|
void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
||||||
{
|
{
|
||||||
Instruction* store = new Instruction(OpStore);
|
Instruction* store = new Instruction(OpStore);
|
||||||
store->addIdOperand(lValue);
|
store->addIdOperand(lValue);
|
||||||
store->addIdOperand(rValue);
|
store->addIdOperand(rValue);
|
||||||
|
|
||||||
|
memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
|
||||||
|
|
||||||
|
if (memoryAccess != MemoryAccessMaskNone) {
|
||||||
|
store->addImmediateOperand(memoryAccess);
|
||||||
|
if (memoryAccess & spv::MemoryAccessAlignedMask) {
|
||||||
|
store->addImmediateOperand(alignment);
|
||||||
|
}
|
||||||
|
if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) {
|
||||||
|
store->addIdOperand(makeUintConstant(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::createLoad(Id lValue)
|
Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
||||||
{
|
{
|
||||||
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
||||||
load->addIdOperand(lValue);
|
load->addIdOperand(lValue);
|
||||||
|
|
||||||
|
memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
|
||||||
|
|
||||||
|
if (memoryAccess != MemoryAccessMaskNone) {
|
||||||
|
load->addImmediateOperand(memoryAccess);
|
||||||
|
if (memoryAccess & spv::MemoryAccessAlignedMask) {
|
||||||
|
load->addImmediateOperand(alignment);
|
||||||
|
}
|
||||||
|
if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) {
|
||||||
|
load->addIdOperand(makeUintConstant(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
||||||
|
|
||||||
return load->getResultId();
|
return load->getResultId();
|
||||||
|
@ -1240,7 +1399,7 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vec
|
||||||
|
|
||||||
Id Builder::createArrayLength(Id base, unsigned int member)
|
Id Builder::createArrayLength(Id base, unsigned int member)
|
||||||
{
|
{
|
||||||
spv::Id intType = makeIntType(32);
|
spv::Id intType = makeUintType(32);
|
||||||
Instruction* length = new Instruction(getUniqueId(), intType, OpArrayLength);
|
Instruction* length = new Instruction(getUniqueId(), intType, OpArrayLength);
|
||||||
length->addIdOperand(base);
|
length->addIdOperand(base);
|
||||||
length->addImmediateOperand(member);
|
length->addImmediateOperand(member);
|
||||||
|
@ -1331,7 +1490,7 @@ void Builder::createNoResultOp(Op opCode)
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
// An opcode that has one operand, no result id, and no type
|
// An opcode that has one id operand, no result id, and no type
|
||||||
void Builder::createNoResultOp(Op opCode, Id operand)
|
void Builder::createNoResultOp(Op opCode, Id operand)
|
||||||
{
|
{
|
||||||
Instruction* op = new Instruction(opCode);
|
Instruction* op = new Instruction(opCode);
|
||||||
|
@ -1339,29 +1498,43 @@ void Builder::createNoResultOp(Op opCode, Id operand)
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
// An opcode that has one operand, no result id, and no type
|
// An opcode that has one or more operands, no result id, and no type
|
||||||
void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
|
void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
|
||||||
{
|
{
|
||||||
Instruction* op = new Instruction(opCode);
|
Instruction* op = new Instruction(opCode);
|
||||||
for (auto it = operands.cbegin(); it != operands.cend(); ++it)
|
for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
|
||||||
op->addIdOperand(*it);
|
op->addIdOperand(*it);
|
||||||
|
}
|
||||||
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
|
}
|
||||||
|
|
||||||
|
// An opcode that has multiple operands, no result id, and no type
|
||||||
|
void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands)
|
||||||
|
{
|
||||||
|
Instruction* op = new Instruction(opCode);
|
||||||
|
for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
|
||||||
|
if (it->isId)
|
||||||
|
op->addIdOperand(it->word);
|
||||||
|
else
|
||||||
|
op->addImmediateOperand(it->word);
|
||||||
|
}
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics)
|
void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics)
|
||||||
{
|
{
|
||||||
Instruction* op = new Instruction(OpControlBarrier);
|
Instruction* op = new Instruction(OpControlBarrier);
|
||||||
op->addImmediateOperand(makeUintConstant(execution));
|
op->addIdOperand(makeUintConstant(execution));
|
||||||
op->addImmediateOperand(makeUintConstant(memory));
|
op->addIdOperand(makeUintConstant(memory));
|
||||||
op->addImmediateOperand(makeUintConstant(semantics));
|
op->addIdOperand(makeUintConstant(semantics));
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics)
|
void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics)
|
||||||
{
|
{
|
||||||
Instruction* op = new Instruction(OpMemoryBarrier);
|
Instruction* op = new Instruction(OpMemoryBarrier);
|
||||||
op->addImmediateOperand(makeUintConstant(executionScope));
|
op->addIdOperand(makeUintConstant(executionScope));
|
||||||
op->addImmediateOperand(makeUintConstant(memorySemantics));
|
op->addIdOperand(makeUintConstant(memorySemantics));
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1428,6 +1601,20 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector<Id>& operands)
|
||||||
return op->getResultId();
|
return op->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id Builder::createOp(Op opCode, Id typeId, const std::vector<IdImmediate>& operands)
|
||||||
|
{
|
||||||
|
Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
|
||||||
|
for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
|
||||||
|
if (it->isId)
|
||||||
|
op->addIdOperand(it->word);
|
||||||
|
else
|
||||||
|
op->addImmediateOperand(it->word);
|
||||||
|
}
|
||||||
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
|
|
||||||
|
return op->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands, const std::vector<unsigned>& literals)
|
Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands, const std::vector<unsigned>& literals)
|
||||||
{
|
{
|
||||||
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
|
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
|
||||||
|
@ -1588,6 +1775,13 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
if (parameters.component != NoResult)
|
if (parameters.component != NoResult)
|
||||||
texArgs[numArgs++] = parameters.component;
|
texArgs[numArgs++] = parameters.component;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (parameters.granularity != NoResult)
|
||||||
|
texArgs[numArgs++] = parameters.granularity;
|
||||||
|
if (parameters.coarse != NoResult)
|
||||||
|
texArgs[numArgs++] = parameters.coarse;
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set up the optional arguments
|
// Set up the optional arguments
|
||||||
//
|
//
|
||||||
|
@ -1639,6 +1833,12 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
|
||||||
texArgs[numArgs++] = parameters.lodClamp;
|
texArgs[numArgs++] = parameters.lodClamp;
|
||||||
}
|
}
|
||||||
|
if (parameters.nonprivate) {
|
||||||
|
mask = mask | ImageOperandsNonPrivateTexelKHRMask;
|
||||||
|
}
|
||||||
|
if (parameters.volatil) {
|
||||||
|
mask = mask | ImageOperandsVolatileTexelKHRMask;
|
||||||
|
}
|
||||||
if (mask == ImageOperandsMaskNone)
|
if (mask == ImageOperandsMaskNone)
|
||||||
--numArgs; // undo speculative reservation for the mask argument
|
--numArgs; // undo speculative reservation for the mask argument
|
||||||
else
|
else
|
||||||
|
@ -1653,6 +1853,10 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
opCode = OpImageSparseFetch;
|
opCode = OpImageSparseFetch;
|
||||||
else
|
else
|
||||||
opCode = OpImageFetch;
|
opCode = OpImageFetch;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
} else if (parameters.granularity && parameters.coarse) {
|
||||||
|
opCode = OpImageSampleFootprintNV;
|
||||||
|
#endif
|
||||||
} else if (gather) {
|
} else if (gather) {
|
||||||
if (parameters.Dref)
|
if (parameters.Dref)
|
||||||
if (sparse)
|
if (sparse)
|
||||||
|
@ -1774,9 +1978,6 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameters, bool isUnsignedResult)
|
Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameters, bool isUnsignedResult)
|
||||||
{
|
{
|
||||||
// All these need a capability
|
|
||||||
addCapability(CapabilityImageQuery);
|
|
||||||
|
|
||||||
// Figure out the result type
|
// Figure out the result type
|
||||||
Id resultType = 0;
|
Id resultType = 0;
|
||||||
switch (opCode) {
|
switch (opCode) {
|
||||||
|
@ -2001,7 +2202,8 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
|
||||||
// Go through the source arguments, each one could have either
|
// Go through the source arguments, each one could have either
|
||||||
// a single or multiple components to contribute.
|
// a single or multiple components to contribute.
|
||||||
for (unsigned int i = 0; i < sources.size(); ++i) {
|
for (unsigned int i = 0; i < sources.size(); ++i) {
|
||||||
if (isScalar(sources[i]))
|
|
||||||
|
if (isScalar(sources[i]) || isPointer(sources[i]))
|
||||||
latchResult(sources[i]);
|
latchResult(sources[i]);
|
||||||
else if (isVector(sources[i]))
|
else if (isVector(sources[i]))
|
||||||
accumulateVectorConstituents(sources[i]);
|
accumulateVectorConstituents(sources[i]);
|
||||||
|
@ -2029,9 +2231,39 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||||
int numRows = getTypeNumRows(resultTypeId);
|
int numRows = getTypeNumRows(resultTypeId);
|
||||||
|
|
||||||
Instruction* instr = module.getInstruction(componentTypeId);
|
Instruction* instr = module.getInstruction(componentTypeId);
|
||||||
Id bitCount = instr->getIdOperand(0);
|
unsigned bitCount = instr->getImmediateOperand(0);
|
||||||
|
|
||||||
// Will use a two step process
|
// Optimize matrix constructed from a bigger matrix
|
||||||
|
if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
|
||||||
|
// To truncate the matrix to a smaller number of rows/columns, we need to:
|
||||||
|
// 1. For each column, extract the column and truncate it to the required size using shuffle
|
||||||
|
// 2. Assemble the resulting matrix from all columns
|
||||||
|
Id matrix = sources[0];
|
||||||
|
Id columnTypeId = getContainedTypeId(resultTypeId);
|
||||||
|
Id sourceColumnTypeId = getContainedTypeId(getTypeId(matrix));
|
||||||
|
|
||||||
|
std::vector<unsigned> channels;
|
||||||
|
for (int row = 0; row < numRows; ++row)
|
||||||
|
channels.push_back(row);
|
||||||
|
|
||||||
|
std::vector<Id> matrixColumns;
|
||||||
|
for (int col = 0; col < numCols; ++col) {
|
||||||
|
std::vector<unsigned> indexes;
|
||||||
|
indexes.push_back(col);
|
||||||
|
Id colv = createCompositeExtract(matrix, sourceColumnTypeId, indexes);
|
||||||
|
setPrecision(colv, precision);
|
||||||
|
|
||||||
|
if (numRows != getNumRows(matrix)) {
|
||||||
|
matrixColumns.push_back(createRvalueSwizzle(precision, columnTypeId, colv, channels));
|
||||||
|
} else {
|
||||||
|
matrixColumns.push_back(colv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, will use a two step process
|
||||||
// 1. make a compile-time 2D array of values
|
// 1. make a compile-time 2D array of values
|
||||||
// 2. construct a matrix from that array
|
// 2. construct a matrix from that array
|
||||||
|
|
||||||
|
@ -2285,11 +2517,16 @@ void Builder::clearAccessChain()
|
||||||
accessChain.component = NoResult;
|
accessChain.component = NoResult;
|
||||||
accessChain.preSwizzleBaseType = NoType;
|
accessChain.preSwizzleBaseType = NoType;
|
||||||
accessChain.isRValue = false;
|
accessChain.isRValue = false;
|
||||||
|
accessChain.coherentFlags.clear();
|
||||||
|
accessChain.alignment = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType)
|
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||||
{
|
{
|
||||||
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
|
accessChain.alignment |= alignment;
|
||||||
|
|
||||||
// swizzles can be stacked in GLSL, but simplified to a single
|
// swizzles can be stacked in GLSL, but simplified to a single
|
||||||
// one here; the base type doesn't change
|
// one here; the base type doesn't change
|
||||||
if (accessChain.preSwizzleBaseType == NoType)
|
if (accessChain.preSwizzleBaseType == NoType)
|
||||||
|
@ -2311,7 +2548,7 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::accessChainStore(Id rvalue)
|
void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
||||||
{
|
{
|
||||||
assert(accessChain.isRValue == false);
|
assert(accessChain.isRValue == false);
|
||||||
|
|
||||||
|
@ -2329,11 +2566,17 @@ void Builder::accessChainStore(Id rvalue)
|
||||||
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
createStore(source, base);
|
// take LSB of alignment
|
||||||
|
alignment = alignment & ~(alignment & (alignment-1));
|
||||||
|
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
|
||||||
|
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
createStore(source, base, memoryAccess, scope, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType)
|
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
||||||
{
|
{
|
||||||
Id id;
|
Id id;
|
||||||
|
|
||||||
|
@ -2376,8 +2619,15 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
||||||
id = accessChain.base; // no precision, it was set when this was defined
|
id = accessChain.base; // no precision, it was set when this was defined
|
||||||
} else {
|
} else {
|
||||||
transferAccessChainSwizzle(true);
|
transferAccessChainSwizzle(true);
|
||||||
|
|
||||||
|
// take LSB of alignment
|
||||||
|
alignment = alignment & ~(alignment & (alignment-1));
|
||||||
|
if (getStorageClass(accessChain.base) == StorageClassPhysicalStorageBufferEXT) {
|
||||||
|
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
|
||||||
|
}
|
||||||
|
|
||||||
// load through the access chain
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain());
|
id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment);
|
||||||
setPrecision(id, precision);
|
setPrecision(id, precision);
|
||||||
addDecoration(id, nonUniform);
|
addDecoration(id, nonUniform);
|
||||||
}
|
}
|
||||||
|
@ -2453,42 +2703,6 @@ Id Builder::accessChainGetInferredType()
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// comment in header
|
|
||||||
void Builder::eliminateDeadDecorations() {
|
|
||||||
std::unordered_set<const Block*> reachable_blocks;
|
|
||||||
std::unordered_set<Id> unreachable_definitions;
|
|
||||||
// Collect IDs defined in unreachable blocks. For each function, label the
|
|
||||||
// reachable blocks first. Then for each unreachable block, collect the
|
|
||||||
// result IDs of the instructions in it.
|
|
||||||
for (std::vector<Function*>::const_iterator fi = module.getFunctions().cbegin();
|
|
||||||
fi != module.getFunctions().cend(); fi++) {
|
|
||||||
Function* f = *fi;
|
|
||||||
Block* entry = f->getEntryBlock();
|
|
||||||
inReadableOrder(entry, [&reachable_blocks](const Block* b) {
|
|
||||||
reachable_blocks.insert(b);
|
|
||||||
});
|
|
||||||
for (std::vector<Block*>::const_iterator bi = f->getBlocks().cbegin();
|
|
||||||
bi != f->getBlocks().cend(); bi++) {
|
|
||||||
Block* b = *bi;
|
|
||||||
if (!reachable_blocks.count(b)) {
|
|
||||||
for (std::vector<std::unique_ptr<Instruction> >::const_iterator
|
|
||||||
ii = b->getInstructions().cbegin();
|
|
||||||
ii != b->getInstructions().cend(); ii++) {
|
|
||||||
Instruction* i = ii->get();
|
|
||||||
unreachable_definitions.insert(i->getResultId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
|
||||||
[&unreachable_definitions](std::unique_ptr<Instruction>& I) -> bool {
|
|
||||||
Instruction* inst = I.get();
|
|
||||||
Id decoration_id = inst->getIdOperand(0);
|
|
||||||
return unreachable_definitions.count(decoration_id) != 0;
|
|
||||||
}),
|
|
||||||
decorations.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Builder::dump(std::vector<unsigned int>& out) const
|
void Builder::dump(std::vector<unsigned int>& out) const
|
||||||
{
|
{
|
||||||
// Header, before first instructions:
|
// Header, before first instructions:
|
||||||
|
@ -2719,7 +2933,8 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
|
||||||
// OpSource
|
// OpSource
|
||||||
// [OpSourceContinued]
|
// [OpSourceContinued]
|
||||||
// ...
|
// ...
|
||||||
void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
void Builder::dumpSourceInstructions(const spv::Id fileId, const std::string& text,
|
||||||
|
std::vector<unsigned int>& out) const
|
||||||
{
|
{
|
||||||
const int maxWordCount = 0xFFFF;
|
const int maxWordCount = 0xFFFF;
|
||||||
const int opSourceWordCount = 4;
|
const int opSourceWordCount = 4;
|
||||||
|
@ -2731,14 +2946,14 @@ void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
||||||
sourceInst.addImmediateOperand(source);
|
sourceInst.addImmediateOperand(source);
|
||||||
sourceInst.addImmediateOperand(sourceVersion);
|
sourceInst.addImmediateOperand(sourceVersion);
|
||||||
// File operand
|
// File operand
|
||||||
if (sourceFileStringId != NoResult) {
|
if (fileId != NoResult) {
|
||||||
sourceInst.addIdOperand(sourceFileStringId);
|
sourceInst.addIdOperand(fileId);
|
||||||
// Source operand
|
// Source operand
|
||||||
if (sourceText.size() > 0) {
|
if (text.size() > 0) {
|
||||||
int nextByte = 0;
|
int nextByte = 0;
|
||||||
std::string subString;
|
std::string subString;
|
||||||
while ((int)sourceText.size() - nextByte > 0) {
|
while ((int)text.size() - nextByte > 0) {
|
||||||
subString = sourceText.substr(nextByte, nonNullBytesPerInstruction);
|
subString = text.substr(nextByte, nonNullBytesPerInstruction);
|
||||||
if (nextByte == 0) {
|
if (nextByte == 0) {
|
||||||
// OpSource
|
// OpSource
|
||||||
sourceInst.addStringOperand(subString.c_str());
|
sourceInst.addStringOperand(subString.c_str());
|
||||||
|
@ -2758,6 +2973,14 @@ void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dump an OpSource[Continued] sequence for the source and every include file
|
||||||
|
void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
dumpSourceInstructions(sourceFileStringId, sourceText, out);
|
||||||
|
for (auto iItr = includeFiles.begin(); iItr != includeFiles.end(); ++iItr)
|
||||||
|
dumpSourceInstructions(iItr->first, *iItr->second, out);
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)instructions.size(); ++i) {
|
for (int i = 0; i < (int)instructions.size(); ++i) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2016 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
@ -57,6 +57,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
|
@ -74,18 +75,33 @@ public:
|
||||||
source = lang;
|
source = lang;
|
||||||
sourceVersion = version;
|
sourceVersion = version;
|
||||||
}
|
}
|
||||||
|
spv::Id getStringId(const std::string& str)
|
||||||
|
{
|
||||||
|
auto sItr = stringIds.find(str);
|
||||||
|
if (sItr != stringIds.end())
|
||||||
|
return sItr->second;
|
||||||
|
spv::Id strId = getUniqueId();
|
||||||
|
Instruction* fileString = new Instruction(strId, NoType, OpString);
|
||||||
|
const char* file_c_str = str.c_str();
|
||||||
|
fileString->addStringOperand(file_c_str);
|
||||||
|
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
||||||
|
stringIds[file_c_str] = strId;
|
||||||
|
return strId;
|
||||||
|
}
|
||||||
void setSourceFile(const std::string& file)
|
void setSourceFile(const std::string& file)
|
||||||
{
|
{
|
||||||
Instruction* fileString = new Instruction(getUniqueId(), NoType, OpString);
|
sourceFileStringId = getStringId(file);
|
||||||
fileString->addStringOperand(file.c_str());
|
|
||||||
sourceFileStringId = fileString->getResultId();
|
|
||||||
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
|
||||||
}
|
}
|
||||||
void setSourceText(const std::string& text) { sourceText = text; }
|
void setSourceText(const std::string& text) { sourceText = text; }
|
||||||
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
|
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
|
||||||
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
|
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
|
||||||
void setEmitOpLines() { emitOpLines = true; }
|
void setEmitOpLines() { emitOpLines = true; }
|
||||||
void addExtension(const char* ext) { extensions.insert(ext); }
|
void addExtension(const char* ext) { extensions.insert(ext); }
|
||||||
|
void addInclude(const std::string& name, const std::string& text)
|
||||||
|
{
|
||||||
|
spv::Id incId = getStringId(name);
|
||||||
|
includeFiles[incId] = &text;
|
||||||
|
}
|
||||||
Id import(const char*);
|
Id import(const char*);
|
||||||
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
||||||
{
|
{
|
||||||
|
@ -106,16 +122,25 @@ public:
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the current line, and if different than the last one,
|
// Generate OpLine for non-filename-based #line directives (ie no filename
|
||||||
// issue a new OpLine, using the current file name.
|
// seen yet): Log the current line, and if different than the last one,
|
||||||
|
// issue a new OpLine using the new line and current source file name.
|
||||||
void setLine(int line);
|
void setLine(int line);
|
||||||
|
|
||||||
|
// If filename null, generate OpLine for non-filename-based line directives,
|
||||||
|
// else do filename-based: Log the current line and file, and if different
|
||||||
|
// than the last one, issue a new OpLine using the new line and file
|
||||||
|
// name.
|
||||||
|
void setLine(int line, const char* filename);
|
||||||
// Low-level OpLine. See setLine() for a layered helper.
|
// Low-level OpLine. See setLine() for a layered helper.
|
||||||
void addLine(Id fileName, int line, int column);
|
void addLine(Id fileName, int line, int column);
|
||||||
|
|
||||||
// For creating new types (will return old type if the requested one was already made).
|
// For creating new types (will return old type if the requested one was already made).
|
||||||
Id makeVoidType();
|
Id makeVoidType();
|
||||||
Id makeBoolType();
|
Id makeBoolType();
|
||||||
Id makePointer(StorageClass, Id type);
|
Id makePointer(StorageClass, Id pointee);
|
||||||
|
Id makeForwardPointer(StorageClass);
|
||||||
|
Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
|
||||||
Id makeIntegerType(int width, bool hasSign); // generic
|
Id makeIntegerType(int width, bool hasSign); // generic
|
||||||
Id makeIntType(int width) { return makeIntegerType(width, true); }
|
Id makeIntType(int width) { return makeIntegerType(width, true); }
|
||||||
Id makeUintType(int width) { return makeIntegerType(width, false); }
|
Id makeUintType(int width) { return makeIntegerType(width, false); }
|
||||||
|
@ -131,6 +156,9 @@ public:
|
||||||
Id makeSamplerType();
|
Id makeSamplerType();
|
||||||
Id makeSampledImageType(Id imageType);
|
Id makeSampledImageType(Id imageType);
|
||||||
|
|
||||||
|
// accelerationStructureNV type
|
||||||
|
Id makeAccelerationStructureNVType();
|
||||||
|
|
||||||
// For querying about types.
|
// For querying about types.
|
||||||
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
||||||
Id getDerefTypeId(Id resultId) const;
|
Id getDerefTypeId(Id resultId) const;
|
||||||
|
@ -167,6 +195,8 @@ public:
|
||||||
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
|
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
|
||||||
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
||||||
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
||||||
|
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
|
||||||
|
bool containsPhysicalStorageBufferOrArray(Id typeId) const;
|
||||||
|
|
||||||
bool isConstantOpCode(Op opcode) const;
|
bool isConstantOpCode(Op opcode) const;
|
||||||
bool isSpecConstantOpCode(Op opcode) const;
|
bool isSpecConstantOpCode(Op opcode) const;
|
||||||
|
@ -273,10 +303,10 @@ public:
|
||||||
Id createUndefined(Id type);
|
Id createUndefined(Id type);
|
||||||
|
|
||||||
// Store into an Id and return the l-value
|
// Store into an Id and return the l-value
|
||||||
void createStore(Id rValue, Id lValue);
|
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
// Load from an Id and return it
|
// Load from an Id and return it
|
||||||
Id createLoad(Id lValue);
|
Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
// Create an OpAccessChain instruction
|
// Create an OpAccessChain instruction
|
||||||
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
||||||
|
@ -296,12 +326,14 @@ public:
|
||||||
void createNoResultOp(Op);
|
void createNoResultOp(Op);
|
||||||
void createNoResultOp(Op, Id operand);
|
void createNoResultOp(Op, Id operand);
|
||||||
void createNoResultOp(Op, const std::vector<Id>& operands);
|
void createNoResultOp(Op, const std::vector<Id>& operands);
|
||||||
|
void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
|
||||||
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
|
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
|
||||||
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
|
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
|
||||||
Id createUnaryOp(Op, Id typeId, Id operand);
|
Id createUnaryOp(Op, Id typeId, Id operand);
|
||||||
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
|
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
|
||||||
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
|
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
|
||||||
Id createOp(Op, Id typeId, const std::vector<Id>& operands);
|
Id createOp(Op, Id typeId, const std::vector<Id>& operands);
|
||||||
|
Id createOp(Op, Id typeId, const std::vector<IdImmediate>& operands);
|
||||||
Id createFunctionCall(spv::Function*, const std::vector<spv::Id>&);
|
Id createFunctionCall(spv::Function*, const std::vector<spv::Id>&);
|
||||||
Id createSpecConstantOp(Op, Id typeId, const std::vector<spv::Id>& operands, const std::vector<unsigned>& literals);
|
Id createSpecConstantOp(Op, Id typeId, const std::vector<spv::Id>& operands, const std::vector<unsigned>& literals);
|
||||||
|
|
||||||
|
@ -363,6 +395,10 @@ public:
|
||||||
Id component;
|
Id component;
|
||||||
Id texelOut;
|
Id texelOut;
|
||||||
Id lodClamp;
|
Id lodClamp;
|
||||||
|
Id granularity;
|
||||||
|
Id coarse;
|
||||||
|
bool nonprivate;
|
||||||
|
bool volatil;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
||||||
|
@ -502,6 +538,44 @@ public:
|
||||||
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
|
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
|
||||||
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
|
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
|
||||||
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
||||||
|
unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment.
|
||||||
|
|
||||||
|
// Accumulate whether anything in the chain of structures has coherent decorations.
|
||||||
|
struct CoherentFlags {
|
||||||
|
unsigned coherent : 1;
|
||||||
|
unsigned devicecoherent : 1;
|
||||||
|
unsigned queuefamilycoherent : 1;
|
||||||
|
unsigned workgroupcoherent : 1;
|
||||||
|
unsigned subgroupcoherent : 1;
|
||||||
|
unsigned nonprivate : 1;
|
||||||
|
unsigned volatil : 1;
|
||||||
|
unsigned isImage : 1;
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
coherent = 0;
|
||||||
|
devicecoherent = 0;
|
||||||
|
queuefamilycoherent = 0;
|
||||||
|
workgroupcoherent = 0;
|
||||||
|
subgroupcoherent = 0;
|
||||||
|
nonprivate = 0;
|
||||||
|
volatil = 0;
|
||||||
|
isImage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoherentFlags() { clear(); }
|
||||||
|
CoherentFlags operator |=(const CoherentFlags &other) {
|
||||||
|
coherent |= other.coherent;
|
||||||
|
devicecoherent |= other.devicecoherent;
|
||||||
|
queuefamilycoherent |= other.queuefamilycoherent;
|
||||||
|
workgroupcoherent |= other.workgroupcoherent;
|
||||||
|
subgroupcoherent |= other.subgroupcoherent;
|
||||||
|
nonprivate |= other.nonprivate;
|
||||||
|
volatil |= other.volatil;
|
||||||
|
isImage |= other.isImage;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
CoherentFlags coherentFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -531,30 +605,34 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// push offset onto the end of the chain
|
// push offset onto the end of the chain
|
||||||
void accessChainPush(Id offset)
|
void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||||
{
|
{
|
||||||
accessChain.indexChain.push_back(offset);
|
accessChain.indexChain.push_back(offset);
|
||||||
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
|
accessChain.alignment |= alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
|
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
|
||||||
|
|
||||||
// push a dynamic component selection onto the access chain, only applicable with a
|
// push a dynamic component selection onto the access chain, only applicable with a
|
||||||
// non-trivial swizzle or no swizzle
|
// non-trivial swizzle or no swizzle
|
||||||
void accessChainPushComponent(Id component, Id preSwizzleBaseType)
|
void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||||
{
|
{
|
||||||
if (accessChain.swizzle.size() != 1) {
|
if (accessChain.swizzle.size() != 1) {
|
||||||
accessChain.component = component;
|
accessChain.component = component;
|
||||||
if (accessChain.preSwizzleBaseType == NoType)
|
if (accessChain.preSwizzleBaseType == NoType)
|
||||||
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
||||||
}
|
}
|
||||||
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
|
accessChain.alignment |= alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use accessChain and swizzle to store value
|
// use accessChain and swizzle to store value
|
||||||
void accessChainStore(Id rvalue);
|
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
// use accessChain and swizzle to load an r-value
|
// use accessChain and swizzle to load an r-value
|
||||||
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType);
|
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
// get the direct pointer for an l-value
|
// get the direct pointer for an l-value
|
||||||
Id accessChainGetLValue();
|
Id accessChainGetLValue();
|
||||||
|
@ -563,9 +641,17 @@ public:
|
||||||
// based on the type of the base and the chain of dereferences.
|
// based on the type of the base and the chain of dereferences.
|
||||||
Id accessChainGetInferredType();
|
Id accessChainGetInferredType();
|
||||||
|
|
||||||
// Remove OpDecorate instructions whose operands are defined in unreachable
|
// Add capabilities, extensions, remove unneeded decorations, etc.,
|
||||||
// blocks.
|
// based on the resulting SPIR-V.
|
||||||
void eliminateDeadDecorations();
|
void postProcess();
|
||||||
|
|
||||||
|
// Hook to visit each instruction in a block in a function
|
||||||
|
void postProcess(Instruction&);
|
||||||
|
// Hook to visit each instruction in a reachable block in a function.
|
||||||
|
void postProcessReachable(const Instruction&);
|
||||||
|
// Hook to visit each non-32-bit sized float/int operation in a block.
|
||||||
|
void postProcessType(const Instruction&, spv::Id typeId);
|
||||||
|
|
||||||
void dump(std::vector<unsigned int>&) const;
|
void dump(std::vector<unsigned int>&) const;
|
||||||
|
|
||||||
void createBranch(Block* block);
|
void createBranch(Block* block);
|
||||||
|
@ -593,8 +679,10 @@ public:
|
||||||
void createAndSetNoPredecessorBlock(const char*);
|
void createAndSetNoPredecessorBlock(const char*);
|
||||||
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
||||||
void dumpSourceInstructions(std::vector<unsigned int>&) const;
|
void dumpSourceInstructions(std::vector<unsigned int>&) const;
|
||||||
|
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
|
||||||
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
||||||
|
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const;
|
||||||
|
|
||||||
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||||
SourceLanguage source;
|
SourceLanguage source;
|
||||||
|
@ -602,6 +690,7 @@ public:
|
||||||
spv::Id sourceFileStringId;
|
spv::Id sourceFileStringId;
|
||||||
std::string sourceText;
|
std::string sourceText;
|
||||||
int currentLine;
|
int currentLine;
|
||||||
|
const char* currentFile;
|
||||||
bool emitOpLines;
|
bool emitOpLines;
|
||||||
std::set<std::string> extensions;
|
std::set<std::string> extensions;
|
||||||
std::vector<const char*> sourceExtensions;
|
std::vector<const char*> sourceExtensions;
|
||||||
|
@ -639,6 +728,12 @@ public:
|
||||||
// Our loop stack.
|
// Our loop stack.
|
||||||
std::stack<LoopBlocks> loops;
|
std::stack<LoopBlocks> loops;
|
||||||
|
|
||||||
|
// map from strings to their string ids
|
||||||
|
std::unordered_map<std::string, spv::Id> stringIds;
|
||||||
|
|
||||||
|
// map from include file name ids to their contents
|
||||||
|
std::map<spv::Id, const std::string*> includeFiles;
|
||||||
|
|
||||||
// The stream for outputting warnings and errors.
|
// The stream for outputting warnings and errors.
|
||||||
SpvBuildLogger* logger;
|
SpvBuildLogger* logger;
|
||||||
}; // end Builder class
|
}; // end Builder class
|
||||||
|
|
390
glslang/spirv/SpvPostProcess.cpp
Normal file
390
glslang/spirv/SpvPostProcess.cpp
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 Google, 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.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Post-processing for SPIR-V IR, in internal form, not standard binary form.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "SpvBuilder.h"
|
||||||
|
|
||||||
|
#include "spirv.hpp"
|
||||||
|
#include "GlslangToSpv.h"
|
||||||
|
#include "SpvBuilder.h"
|
||||||
|
namespace spv {
|
||||||
|
#include "GLSL.std.450.h"
|
||||||
|
#include "GLSL.ext.KHR.h"
|
||||||
|
#include "GLSL.ext.EXT.h"
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
#include "GLSL.ext.AMD.h"
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
#include "GLSL.ext.NV.h"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
// Hook to visit each operand type and result type of an instruction.
|
||||||
|
// Will be called multiple times for one instruction, once for each typed
|
||||||
|
// operand and the result.
|
||||||
|
void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||||
|
{
|
||||||
|
// Characterize the type being questioned
|
||||||
|
Id basicTypeOp = getMostBasicTypeClass(typeId);
|
||||||
|
int width = 0;
|
||||||
|
if (basicTypeOp == OpTypeFloat || basicTypeOp == OpTypeInt)
|
||||||
|
width = getScalarTypeWidth(typeId);
|
||||||
|
|
||||||
|
// Do opcode-specific checks
|
||||||
|
switch (inst.getOpCode()) {
|
||||||
|
case OpLoad:
|
||||||
|
case OpStore:
|
||||||
|
if (basicTypeOp == OpTypeStruct) {
|
||||||
|
if (containsType(typeId, OpTypeInt, 8))
|
||||||
|
addCapability(CapabilityInt8);
|
||||||
|
if (containsType(typeId, OpTypeInt, 16))
|
||||||
|
addCapability(CapabilityInt16);
|
||||||
|
if (containsType(typeId, OpTypeFloat, 16))
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
} else {
|
||||||
|
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
|
||||||
|
if (width == 8) {
|
||||||
|
switch (storageClass) {
|
||||||
|
case StorageClassPhysicalStorageBufferEXT:
|
||||||
|
case StorageClassUniform:
|
||||||
|
case StorageClassStorageBuffer:
|
||||||
|
case StorageClassPushConstant:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
addCapability(CapabilityInt8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (width == 16) {
|
||||||
|
switch (storageClass) {
|
||||||
|
case StorageClassPhysicalStorageBufferEXT:
|
||||||
|
case StorageClassUniform:
|
||||||
|
case StorageClassStorageBuffer:
|
||||||
|
case StorageClassPushConstant:
|
||||||
|
case StorageClassInput:
|
||||||
|
case StorageClassOutput:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (basicTypeOp == OpTypeInt)
|
||||||
|
addCapability(CapabilityInt16);
|
||||||
|
if (basicTypeOp == OpTypeFloat)
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OpAccessChain:
|
||||||
|
case OpPtrAccessChain:
|
||||||
|
case OpCopyObject:
|
||||||
|
case OpFConvert:
|
||||||
|
case OpSConvert:
|
||||||
|
case OpUConvert:
|
||||||
|
break;
|
||||||
|
case OpExtInst:
|
||||||
|
#if AMD_EXTENSIONS
|
||||||
|
switch (inst.getImmediateOperand(1)) {
|
||||||
|
case GLSLstd450Frexp:
|
||||||
|
case GLSLstd450FrexpStruct:
|
||||||
|
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeInt, 16))
|
||||||
|
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
|
||||||
|
break;
|
||||||
|
case GLSLstd450InterpolateAtCentroid:
|
||||||
|
case GLSLstd450InterpolateAtSample:
|
||||||
|
case GLSLstd450InterpolateAtOffset:
|
||||||
|
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeFloat, 16))
|
||||||
|
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (basicTypeOp == OpTypeFloat && width == 16)
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
if (basicTypeOp == OpTypeInt && width == 16)
|
||||||
|
addCapability(CapabilityInt16);
|
||||||
|
if (basicTypeOp == OpTypeInt && width == 8)
|
||||||
|
addCapability(CapabilityInt8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called for each instruction that resides in a block.
|
||||||
|
void Builder::postProcess(Instruction& inst)
|
||||||
|
{
|
||||||
|
// Add capabilities based simply on the opcode.
|
||||||
|
switch (inst.getOpCode()) {
|
||||||
|
case OpExtInst:
|
||||||
|
switch (inst.getImmediateOperand(1)) {
|
||||||
|
case GLSLstd450InterpolateAtCentroid:
|
||||||
|
case GLSLstd450InterpolateAtSample:
|
||||||
|
case GLSLstd450InterpolateAtOffset:
|
||||||
|
addCapability(CapabilityInterpolationFunction);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OpDPdxFine:
|
||||||
|
case OpDPdyFine:
|
||||||
|
case OpFwidthFine:
|
||||||
|
case OpDPdxCoarse:
|
||||||
|
case OpDPdyCoarse:
|
||||||
|
case OpFwidthCoarse:
|
||||||
|
addCapability(CapabilityDerivativeControl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpImageQueryLod:
|
||||||
|
case OpImageQuerySize:
|
||||||
|
case OpImageQuerySizeLod:
|
||||||
|
case OpImageQuerySamples:
|
||||||
|
case OpImageQueryLevels:
|
||||||
|
addCapability(CapabilityImageQuery);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case OpGroupNonUniformPartitionNV:
|
||||||
|
addExtension(E_SPV_NV_shader_subgroup_partitioned);
|
||||||
|
addCapability(CapabilityGroupNonUniformPartitionedNV);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case OpLoad:
|
||||||
|
case OpStore:
|
||||||
|
{
|
||||||
|
// For any load/store to a PhysicalStorageBufferEXT, walk the accesschain
|
||||||
|
// index list to compute the misalignment. The pre-existing alignment value
|
||||||
|
// (set via Builder::AccessChain::alignment) only accounts for the base of
|
||||||
|
// the reference type and any scalar component selection in the accesschain,
|
||||||
|
// and this function computes the rest from the SPIR-V Offset decorations.
|
||||||
|
Instruction *accessChain = module.getInstruction(inst.getIdOperand(0));
|
||||||
|
if (accessChain->getOpCode() == OpAccessChain) {
|
||||||
|
Instruction *base = module.getInstruction(accessChain->getIdOperand(0));
|
||||||
|
// Get the type of the base of the access chain. It must be a pointer type.
|
||||||
|
Id typeId = base->getTypeId();
|
||||||
|
Instruction *type = module.getInstruction(typeId);
|
||||||
|
assert(type->getOpCode() == OpTypePointer);
|
||||||
|
if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Get the pointee type.
|
||||||
|
typeId = type->getIdOperand(1);
|
||||||
|
type = module.getInstruction(typeId);
|
||||||
|
// Walk the index list for the access chain. For each index, find any
|
||||||
|
// misalignment that can apply when accessing the member/element via
|
||||||
|
// Offset/ArrayStride/MatrixStride decorations, and bitwise OR them all
|
||||||
|
// together.
|
||||||
|
int alignment = 0;
|
||||||
|
for (int i = 1; i < accessChain->getNumOperands(); ++i) {
|
||||||
|
Instruction *idx = module.getInstruction(accessChain->getIdOperand(i));
|
||||||
|
if (type->getOpCode() == OpTypeStruct) {
|
||||||
|
assert(idx->getOpCode() == OpConstant);
|
||||||
|
unsigned int c = idx->getImmediateOperand(0);
|
||||||
|
|
||||||
|
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||||
|
if (decoration.get()->getOpCode() == OpMemberDecorate &&
|
||||||
|
decoration.get()->getIdOperand(0) == typeId &&
|
||||||
|
decoration.get()->getImmediateOperand(1) == c &&
|
||||||
|
(decoration.get()->getImmediateOperand(2) == DecorationOffset ||
|
||||||
|
decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) {
|
||||||
|
alignment |= decoration.get()->getImmediateOperand(3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::for_each(decorations.begin(), decorations.end(), function);
|
||||||
|
// get the next member type
|
||||||
|
typeId = type->getIdOperand(c);
|
||||||
|
type = module.getInstruction(typeId);
|
||||||
|
} else if (type->getOpCode() == OpTypeArray ||
|
||||||
|
type->getOpCode() == OpTypeRuntimeArray) {
|
||||||
|
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||||
|
if (decoration.get()->getOpCode() == OpDecorate &&
|
||||||
|
decoration.get()->getIdOperand(0) == typeId &&
|
||||||
|
decoration.get()->getImmediateOperand(1) == DecorationArrayStride) {
|
||||||
|
alignment |= decoration.get()->getImmediateOperand(2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::for_each(decorations.begin(), decorations.end(), function);
|
||||||
|
// Get the element type
|
||||||
|
typeId = type->getIdOperand(0);
|
||||||
|
type = module.getInstruction(typeId);
|
||||||
|
} else {
|
||||||
|
// Once we get to any non-aggregate type, we're done.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(inst.getNumOperands() >= 3);
|
||||||
|
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
|
||||||
|
assert(memoryAccess & MemoryAccessAlignedMask);
|
||||||
|
// Compute the index of the alignment operand.
|
||||||
|
int alignmentIdx = 2;
|
||||||
|
if (memoryAccess & MemoryAccessVolatileMask)
|
||||||
|
alignmentIdx++;
|
||||||
|
if (inst.getOpCode() == OpStore)
|
||||||
|
alignmentIdx++;
|
||||||
|
// Merge new and old (mis)alignment
|
||||||
|
alignment |= inst.getImmediateOperand(alignmentIdx);
|
||||||
|
// Pick the LSB
|
||||||
|
alignment = alignment & ~(alignment & (alignment-1));
|
||||||
|
// update the Aligned operand
|
||||||
|
inst.setImmediateOperand(alignmentIdx, alignment);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks based on type
|
||||||
|
if (inst.getTypeId() != NoType)
|
||||||
|
postProcessType(inst, inst.getTypeId());
|
||||||
|
for (int op = 0; op < inst.getNumOperands(); ++op) {
|
||||||
|
if (inst.isIdOperand(op)) {
|
||||||
|
// In blocks, these are always result ids, but we are relying on
|
||||||
|
// getTypeId() to return NoType for things like OpLabel.
|
||||||
|
if (getTypeId(inst.getIdOperand(op)) != NoType)
|
||||||
|
postProcessType(inst, getTypeId(inst.getIdOperand(op)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called for each instruction in a reachable block.
|
||||||
|
void Builder::postProcessReachable(const Instruction&)
|
||||||
|
{
|
||||||
|
// did have code here, but questionable to do so without deleting the instructions
|
||||||
|
}
|
||||||
|
|
||||||
|
// comment in header
|
||||||
|
void Builder::postProcess()
|
||||||
|
{
|
||||||
|
std::unordered_set<const Block*> reachableBlocks;
|
||||||
|
std::unordered_set<Id> unreachableDefinitions;
|
||||||
|
// Collect IDs defined in unreachable blocks. For each function, label the
|
||||||
|
// reachable blocks first. Then for each unreachable block, collect the
|
||||||
|
// result IDs of the instructions in it.
|
||||||
|
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||||
|
Function* f = *fi;
|
||||||
|
Block* entry = f->getEntryBlock();
|
||||||
|
inReadableOrder(entry, [&reachableBlocks](const Block* b) { reachableBlocks.insert(b); });
|
||||||
|
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||||
|
Block* b = *bi;
|
||||||
|
if (reachableBlocks.count(b) == 0) {
|
||||||
|
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
||||||
|
unreachableDefinitions.insert(ii->get()->getResultId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unneeded decorations, for unreachable instructions
|
||||||
|
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
||||||
|
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
|
||||||
|
Id decoration_id = I.get()->getIdOperand(0);
|
||||||
|
return unreachableDefinitions.count(decoration_id) != 0;
|
||||||
|
}),
|
||||||
|
decorations.end());
|
||||||
|
|
||||||
|
// Add per-instruction capabilities, extensions, etc.,
|
||||||
|
|
||||||
|
// process all reachable instructions...
|
||||||
|
for (auto bi = reachableBlocks.cbegin(); bi != reachableBlocks.cend(); ++bi) {
|
||||||
|
const Block* block = *bi;
|
||||||
|
const auto function = [this](const std::unique_ptr<Instruction>& inst) { postProcessReachable(*inst.get()); };
|
||||||
|
std::for_each(block->getInstructions().begin(), block->getInstructions().end(), function);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process all block-contained instructions
|
||||||
|
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||||
|
Function* f = *fi;
|
||||||
|
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||||
|
Block* b = *bi;
|
||||||
|
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
||||||
|
postProcess(*ii->get());
|
||||||
|
|
||||||
|
// For all local variables that contain pointers to PhysicalStorageBufferEXT, check whether
|
||||||
|
// there is an existing restrict/aliased decoration. If we don't find one, add Aliased as the
|
||||||
|
// default.
|
||||||
|
for (auto vi = b->getLocalVariables().cbegin(); vi != b->getLocalVariables().cend(); vi++) {
|
||||||
|
const Instruction& inst = *vi->get();
|
||||||
|
Id resultId = inst.getResultId();
|
||||||
|
if (containsPhysicalStorageBufferOrArray(getDerefTypeId(resultId))) {
|
||||||
|
bool foundDecoration = false;
|
||||||
|
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||||
|
if (decoration.get()->getIdOperand(0) == resultId &&
|
||||||
|
decoration.get()->getOpCode() == OpDecorate &&
|
||||||
|
(decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT ||
|
||||||
|
decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) {
|
||||||
|
foundDecoration = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::for_each(decorations.begin(), decorations.end(), function);
|
||||||
|
if (!foundDecoration) {
|
||||||
|
addDecoration(resultId, spv::DecorationAliasedPointerEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for any 8/16 bit type in physical storage buffer class, and set the
|
||||||
|
// appropriate capability. This happens in createSpvVariable for other storage
|
||||||
|
// classes, but there isn't always a variable for physical storage buffer.
|
||||||
|
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
||||||
|
Instruction* type = groupedTypes[OpTypePointer][t];
|
||||||
|
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
|
||||||
|
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
|
||||||
|
addExtension(spv::E_SPV_KHR_8bit_storage);
|
||||||
|
addCapability(spv::CapabilityStorageBuffer8BitAccess);
|
||||||
|
}
|
||||||
|
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
|
||||||
|
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
|
||||||
|
addExtension(spv::E_SPV_KHR_16bit_storage);
|
||||||
|
addCapability(spv::CapabilityStorageBuffer16BitAccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end spv namespace
|
199
glslang/spirv/SpvTools.cpp
Normal file
199
glslang/spirv/SpvTools.cpp
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2018 Google, 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.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if ENABLE_OPT
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "SpvTools.h"
|
||||||
|
#include "spirv-tools/optimizer.hpp"
|
||||||
|
#include "spirv-tools/libspirv.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
||||||
|
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger)
|
||||||
|
{
|
||||||
|
switch (spvVersion.vulkan) {
|
||||||
|
case glslang::EShTargetVulkan_1_0: return spv_target_env::SPV_ENV_VULKAN_1_0;
|
||||||
|
case glslang::EShTargetVulkan_1_1: return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spvVersion.openGl > 0)
|
||||||
|
return spv_target_env::SPV_ENV_OPENGL_4_5;
|
||||||
|
|
||||||
|
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||||
|
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
||||||
|
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
||||||
|
{
|
||||||
|
// disassemble
|
||||||
|
spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
|
||||||
|
spv_text text;
|
||||||
|
spv_diagnostic diagnostic = nullptr;
|
||||||
|
spvBinaryToText(context, spirv.data(), spirv.size(),
|
||||||
|
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
|
||||||
|
&text, &diagnostic);
|
||||||
|
|
||||||
|
// dump
|
||||||
|
if (diagnostic == nullptr)
|
||||||
|
out << text->str;
|
||||||
|
else
|
||||||
|
spvDiagnosticPrint(diagnostic);
|
||||||
|
|
||||||
|
// teardown
|
||||||
|
spvDiagnosticDestroy(diagnostic);
|
||||||
|
spvContextDestroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||||
|
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger* logger)
|
||||||
|
{
|
||||||
|
// validate
|
||||||
|
spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||||
|
spv_const_binary_t binary = { spirv.data(), spirv.size() };
|
||||||
|
spv_diagnostic diagnostic = nullptr;
|
||||||
|
spv_validator_options options = spvValidatorOptionsCreate();
|
||||||
|
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
|
||||||
|
spvValidateWithOptions(context, options, &binary, &diagnostic);
|
||||||
|
|
||||||
|
// report
|
||||||
|
if (diagnostic != nullptr) {
|
||||||
|
logger->error("SPIRV-Tools Validation Errors");
|
||||||
|
logger->error(diagnostic->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tear down
|
||||||
|
spvValidatorOptionsDestroy(options);
|
||||||
|
spvDiagnosticDestroy(diagnostic);
|
||||||
|
spvContextDestroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
||||||
|
// legalizing HLSL SPIR-V.
|
||||||
|
void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger*, const SpvOptions* options)
|
||||||
|
{
|
||||||
|
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
|
||||||
|
|
||||||
|
spvtools::Optimizer optimizer(target_env);
|
||||||
|
optimizer.SetMessageConsumer(
|
||||||
|
[](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) {
|
||||||
|
auto &out = std::cerr;
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case SPV_MSG_FATAL:
|
||||||
|
case SPV_MSG_INTERNAL_ERROR:
|
||||||
|
case SPV_MSG_ERROR:
|
||||||
|
out << "error: ";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_WARNING:
|
||||||
|
out << "warning: ";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_INFO:
|
||||||
|
case SPV_MSG_DEBUG:
|
||||||
|
out << "info: ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
out << source << ":";
|
||||||
|
}
|
||||||
|
out << position.line << ":" << position.column << ":" << position.index << ":";
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
out << " " << message;
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
// If debug (specifically source line info) is being generated, propagate
|
||||||
|
// line information into all SPIR-V instructions. This avoids loss of
|
||||||
|
// information when instructions are deleted or moved. Later, remove
|
||||||
|
// redundant information to minimize final SPRIR-V size.
|
||||||
|
if (options->generateDebugInfo) {
|
||||||
|
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
|
||||||
|
}
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateEliminateDeadFunctionsPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateScalarReplacementPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalAccessChainConvertPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalSingleBlockLoadStoreElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalSingleStoreElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateBlockMergePass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalMultiStoreElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateIfConversionPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||||
|
if (options->optimizeSize) {
|
||||||
|
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
|
||||||
|
// TODO(greg-lunarg): Add this when AMD driver issues are resolved
|
||||||
|
// optimizer.RegisterPass(CreateCommonUniformElimPass());
|
||||||
|
}
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
||||||
|
if (options->generateDebugInfo) {
|
||||||
|
optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass());
|
||||||
|
}
|
||||||
|
|
||||||
|
optimizer.Run(spirv.data(), spirv.size(), &spirv);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end namespace glslang
|
||||||
|
|
||||||
|
#endif
|
80
glslang/spirv/SpvTools.h
Normal file
80
glslang/spirv/SpvTools.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2018 Google, 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.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef GLSLANG_SPV_TOOLS_H
|
||||||
|
#define GLSLANG_SPV_TOOLS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "../glslang/MachineIndependent/localintermediate.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
struct SpvOptions {
|
||||||
|
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
||||||
|
optimizeSize(false), disassemble(false), validate(false) { }
|
||||||
|
bool generateDebugInfo;
|
||||||
|
bool disableOptimizer;
|
||||||
|
bool optimizeSize;
|
||||||
|
bool disassemble;
|
||||||
|
bool validate;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ENABLE_OPT
|
||||||
|
|
||||||
|
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
||||||
|
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||||
|
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger*);
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
||||||
|
// legalizing HLSL SPIR-V.
|
||||||
|
void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger*, const SpvOptions*);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}; // end namespace glslang
|
||||||
|
|
||||||
|
#endif // GLSLANG_SPV_TOOLS_H
|
|
@ -26,7 +26,7 @@ Dest BitwiseCast(Src source) {
|
||||||
Dest dest;
|
Dest dest;
|
||||||
static_assert(sizeof(source) == sizeof(dest),
|
static_assert(sizeof(source) == sizeof(dest),
|
||||||
"BitwiseCast: Source and destination must have the same size");
|
"BitwiseCast: Source and destination must have the same size");
|
||||||
std::memcpy(&dest, &source, sizeof(dest));
|
std::memcpy(static_cast<void*>(&dest), &source, sizeof(dest));
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
#include "disassemble.h"
|
#include "disassemble.h"
|
||||||
#include "doc.h"
|
#include "doc.h"
|
||||||
|
#include "SpvTools.h"
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -509,7 +510,9 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
}else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
|
}else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
|
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) {
|
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) {
|
||||||
extInstSet = GLSLextNVInst;
|
extInstSet = GLSLextNVInst;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -534,6 +537,19 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
case OperandLiteralString:
|
case OperandLiteralString:
|
||||||
numOperands -= disassembleString();
|
numOperands -= disassembleString();
|
||||||
break;
|
break;
|
||||||
|
case OperandMemoryAccess:
|
||||||
|
outputMask(OperandMemoryAccess, stream[word++]);
|
||||||
|
--numOperands;
|
||||||
|
// Aligned is the only memory access operand that uses an immediate
|
||||||
|
// value, and it is also the first operand that uses a value at all.
|
||||||
|
if (stream[word-1] & MemoryAccessAlignedMask) {
|
||||||
|
disassembleImmediates(1);
|
||||||
|
numOperands--;
|
||||||
|
if (numOperands)
|
||||||
|
out << " ";
|
||||||
|
}
|
||||||
|
disassembleIds(numOperands);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
|
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
|
||||||
|
|
||||||
|
@ -685,21 +701,45 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 ||
|
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 ||
|
||||||
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
||||||
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
||||||
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) {
|
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_mesh_shader) == 0) {
|
||||||
switch (entrypoint) {
|
switch (entrypoint) {
|
||||||
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
// NV builtins
|
||||||
case DecorationPassthroughNV: return "PassthroughNV";
|
|
||||||
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
|
||||||
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
|
||||||
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
|
||||||
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
|
||||||
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
|
||||||
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||||
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
|
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
||||||
|
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
|
case BuiltInTaskCountNV: return "TaskCountNV";
|
||||||
|
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
|
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||||
|
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
|
||||||
|
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
|
||||||
|
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
|
||||||
|
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
|
||||||
|
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||||
|
|
||||||
|
// NV Capabilities
|
||||||
|
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||||
|
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||||
|
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
||||||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
|
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||||
|
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||||
|
|
||||||
|
// NV Decorations
|
||||||
|
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||||
|
case DecorationPassthroughNV: return "PassthroughNV";
|
||||||
|
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||||
|
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
||||||
|
case DecorationPerVertexNV: return "PerVertexNV";
|
||||||
|
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
|
||||||
|
case DecorationPerViewNV: return "PerViewNV";
|
||||||
|
case DecorationPerTaskNV: return "PerTaskNV";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -716,25 +756,4 @@ void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
||||||
SpirvStream.processInstructions();
|
SpirvStream.processInstructions();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_OPT
|
|
||||||
|
|
||||||
#include "spirv-tools/libspirv.h"
|
|
||||||
|
|
||||||
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
|
||||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
|
||||||
{
|
|
||||||
spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
|
|
||||||
spv_text text;
|
|
||||||
spv_diagnostic diagnostic = nullptr;
|
|
||||||
spvBinaryToText(context, &spirv.front(), spirv.size(),
|
|
||||||
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
|
|
||||||
&text, &diagnostic);
|
|
||||||
if (diagnostic == nullptr)
|
|
||||||
out << text->str;
|
|
||||||
else
|
|
||||||
spvDiagnosticPrint(diagnostic);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}; // end namespace spv
|
}; // end namespace spv
|
||||||
|
|
|
@ -48,9 +48,6 @@ namespace spv {
|
||||||
// disassemble with glslang custom disassembler
|
// disassemble with glslang custom disassembler
|
||||||
void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
||||||
|
|
||||||
// disassemble with SPIRV-Tools disassembler
|
|
||||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& stream);
|
|
||||||
|
|
||||||
}; // end namespace spv
|
}; // end namespace spv
|
||||||
|
|
||||||
#endif // disassembler_H
|
#endif // disassembler_H
|
||||||
|
|
|
@ -98,8 +98,22 @@ const char* ExecutionModelString(int model)
|
||||||
case 4: return "Fragment";
|
case 4: return "Fragment";
|
||||||
case 5: return "GLCompute";
|
case 5: return "GLCompute";
|
||||||
case 6: return "Kernel";
|
case 6: return "Kernel";
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case ExecutionModelTaskNV: return "TaskNV";
|
||||||
|
case ExecutionModelMeshNV: return "MeshNV";
|
||||||
|
#endif
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case ExecutionModelRayGenerationNV: return "RayGenerationNV";
|
||||||
|
case ExecutionModelIntersectionNV: return "IntersectionNV";
|
||||||
|
case ExecutionModelAnyHitNV: return "AnyHitNV";
|
||||||
|
case ExecutionModelClosestHitNV: return "ClosestHitNV";
|
||||||
|
case ExecutionModelMissNV: return "MissNV";
|
||||||
|
case ExecutionModelCallableNV: return "CallableNV";
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +124,8 @@ const char* AddressingString(int addr)
|
||||||
case 1: return "Physical32";
|
case 1: return "Physical32";
|
||||||
case 2: return "Physical64";
|
case 2: return "Physical64";
|
||||||
|
|
||||||
|
case AddressingModelPhysicalStorageBuffer64EXT: return "PhysicalStorageBuffer64EXT";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,9 +133,10 @@ const char* AddressingString(int addr)
|
||||||
const char* MemoryString(int mem)
|
const char* MemoryString(int mem)
|
||||||
{
|
{
|
||||||
switch (mem) {
|
switch (mem) {
|
||||||
case 0: return "Simple";
|
case MemoryModelSimple: return "Simple";
|
||||||
case 1: return "GLSL450";
|
case MemoryModelGLSL450: return "GLSL450";
|
||||||
case 2: return "OpenCL";
|
case MemoryModelOpenCL: return "OpenCL";
|
||||||
|
case MemoryModelVulkanKHR: return "VulkanKHR";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
|
@ -165,6 +182,15 @@ const char* ExecutionModeString(int mode)
|
||||||
case 32: return "Bad";
|
case 32: return "Bad";
|
||||||
|
|
||||||
case 4446: return "PostDepthCoverage";
|
case 4446: return "PostDepthCoverage";
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
|
||||||
|
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
|
||||||
|
case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV";
|
||||||
|
case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV";
|
||||||
|
case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV";
|
||||||
|
#endif
|
||||||
|
|
||||||
case ExecutionModeCeiling:
|
case ExecutionModeCeiling:
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
|
@ -187,6 +213,17 @@ const char* StorageClassString(int StorageClass)
|
||||||
case 11: return "Image";
|
case 11: return "Image";
|
||||||
case 12: return "StorageBuffer";
|
case 12: return "StorageBuffer";
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case StorageClassRayPayloadNV: return "RayPayloadNV";
|
||||||
|
case StorageClassHitAttributeNV: return "HitAttributeNV";
|
||||||
|
case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV";
|
||||||
|
case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV";
|
||||||
|
case StorageClassCallableDataNV: return "CallableDataNV";
|
||||||
|
case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,11 +290,17 @@ const char* DecorationString(int decoration)
|
||||||
case DecorationPassthroughNV: return "PassthroughNV";
|
case DecorationPassthroughNV: return "PassthroughNV";
|
||||||
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||||
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
||||||
|
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
|
||||||
|
case DecorationPerViewNV: return "PerViewNV";
|
||||||
|
case DecorationPerTaskNV: return "PerTaskNV";
|
||||||
|
case DecorationPerVertexNV: return "PerVertexNV";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
||||||
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
||||||
case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE";
|
case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE";
|
||||||
|
case DecorationRestrictPointerEXT: return "DecorationRestrictPointerEXT";
|
||||||
|
case DecorationAliasedPointerEXT: return "DecorationAliasedPointerEXT";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,15 +375,48 @@ const char* BuiltInString(int builtIn)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case 5253: return "ViewportMaskNV";
|
case BuiltInLaunchIdNV: return "LaunchIdNV";
|
||||||
case 5257: return "SecondaryPositionNV";
|
case BuiltInLaunchSizeNV: return "LaunchSizeNV";
|
||||||
case 5258: return "SecondaryViewportMaskNV";
|
case BuiltInWorldRayOriginNV: return "WorldRayOriginNV";
|
||||||
case 5261: return "PositionPerViewNV";
|
case BuiltInWorldRayDirectionNV: return "WorldRayDirectionNV";
|
||||||
case 5262: return "ViewportMaskPerViewNV";
|
case BuiltInObjectRayOriginNV: return "ObjectRayOriginNV";
|
||||||
|
case BuiltInObjectRayDirectionNV: return "ObjectRayDirectionNV";
|
||||||
|
case BuiltInRayTminNV: return "RayTminNV";
|
||||||
|
case BuiltInRayTmaxNV: return "RayTmaxNV";
|
||||||
|
case BuiltInInstanceCustomIndexNV: return "InstanceCustomIndexNV";
|
||||||
|
case BuiltInObjectToWorldNV: return "ObjectToWorldNV";
|
||||||
|
case BuiltInWorldToObjectNV: return "WorldToObjectNV";
|
||||||
|
case BuiltInHitTNV: return "HitTNV";
|
||||||
|
case BuiltInHitKindNV: return "HitKindNV";
|
||||||
|
case BuiltInIncomingRayFlagsNV: return "IncomingRayFlagsNV";
|
||||||
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
|
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
|
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
|
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||||
|
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
|
// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
|
||||||
|
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
|
||||||
|
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
||||||
|
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case BuiltInFragSizeEXT: return "FragSizeEXT";
|
||||||
|
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
|
||||||
case 5264: return "FullyCoveredEXT";
|
case 5264: return "FullyCoveredEXT";
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case BuiltInTaskCountNV: return "TaskCountNV";
|
||||||
|
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
|
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||||
|
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
|
||||||
|
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
|
||||||
|
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
|
||||||
|
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
|
||||||
|
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||||
|
#endif
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,19 +575,23 @@ const char* ImageChannelDataTypeString(int type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ImageOperandsCeiling = 8;
|
const int ImageOperandsCeiling = 12;
|
||||||
|
|
||||||
const char* ImageOperandsString(int format)
|
const char* ImageOperandsString(int format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0: return "Bias";
|
case ImageOperandsBiasShift: return "Bias";
|
||||||
case 1: return "Lod";
|
case ImageOperandsLodShift: return "Lod";
|
||||||
case 2: return "Grad";
|
case ImageOperandsGradShift: return "Grad";
|
||||||
case 3: return "ConstOffset";
|
case ImageOperandsConstOffsetShift: return "ConstOffset";
|
||||||
case 4: return "Offset";
|
case ImageOperandsOffsetShift: return "Offset";
|
||||||
case 5: return "ConstOffsets";
|
case ImageOperandsConstOffsetsShift: return "ConstOffsets";
|
||||||
case 6: return "Sample";
|
case ImageOperandsSampleShift: return "Sample";
|
||||||
case 7: return "MinLod";
|
case ImageOperandsMinLodShift: return "MinLod";
|
||||||
|
case ImageOperandsMakeTexelAvailableKHRShift: return "MakeTexelAvailableKHR";
|
||||||
|
case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR";
|
||||||
|
case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR";
|
||||||
|
case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR";
|
||||||
|
|
||||||
case ImageOperandsCeiling:
|
case ImageOperandsCeiling:
|
||||||
default:
|
default:
|
||||||
|
@ -645,12 +725,17 @@ const char* MemorySemanticsString(int mem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int MemoryAccessCeiling = 6;
|
||||||
|
|
||||||
const char* MemoryAccessString(int mem)
|
const char* MemoryAccessString(int mem)
|
||||||
{
|
{
|
||||||
switch (mem) {
|
switch (mem) {
|
||||||
case 0: return "Volatile";
|
case MemoryAccessVolatileShift: return "Volatile";
|
||||||
case 1: return "Aligned";
|
case MemoryAccessAlignedShift: return "Aligned";
|
||||||
case 2: return "Nontemporal";
|
case MemoryAccessNontemporalShift: return "Nontemporal";
|
||||||
|
case MemoryAccessMakePointerAvailableKHRShift: return "MakePointerAvailableKHR";
|
||||||
|
case MemoryAccessMakePointerVisibleKHRShift: return "MakePointerVisibleKHR";
|
||||||
|
case MemoryAccessNonPrivatePointerKHRShift: return "NonPrivatePointerKHR";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
|
@ -810,13 +895,20 @@ const char* CapabilityString(int info)
|
||||||
|
|
||||||
case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage";
|
case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage";
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||||
case CapabilityShaderViewportIndexLayerNV: return "ShaderViewportIndexLayerNV";
|
case CapabilityShaderViewportIndexLayerNV: return "ShaderViewportIndexLayerNV";
|
||||||
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||||
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
||||||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
|
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
|
||||||
|
case CapabilityRayTracingNV: return "RayTracingNV";
|
||||||
|
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
|
||||||
|
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
||||||
|
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||||
|
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||||
|
// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by CapabilityFragmentDensityEXT
|
||||||
#endif
|
#endif
|
||||||
|
case CapabilityFragmentDensityEXT: return "FragmentDensityEXT";
|
||||||
|
|
||||||
case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";
|
case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";
|
||||||
|
|
||||||
|
@ -833,6 +925,11 @@ const char* CapabilityString(int info)
|
||||||
case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
|
case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
|
||||||
case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
|
case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
|
||||||
|
|
||||||
|
case CapabilityVulkanMemoryModelKHR: return "CapabilityVulkanMemoryModelKHR";
|
||||||
|
case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR";
|
||||||
|
|
||||||
|
case CapabilityPhysicalStorageBufferAddressesEXT: return "CapabilityPhysicalStorageBufferAddressesEXT";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1225,8 +1322,17 @@ const char* OpcodeString(int op)
|
||||||
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
|
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
|
||||||
|
case OpReportIntersectionNV: return "OpReportIntersectionNV";
|
||||||
|
case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
|
||||||
|
case OpTerminateRayNV: return "OpTerminateRayNV";
|
||||||
|
case OpTraceNV: return "OpTraceNV";
|
||||||
|
case OpTypeAccelerationStructureNV: return "OpTypeAccelerationStructureNV";
|
||||||
|
case OpExecuteCallableNV: return "OpExecuteCallableNV";
|
||||||
|
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
|
||||||
|
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "Bad";
|
return "Bad";
|
||||||
}
|
}
|
||||||
|
@ -1245,6 +1351,7 @@ EnumParameters DecorationParams[DecorationCeiling];
|
||||||
EnumParameters LoopControlParams[FunctionControlCeiling];
|
EnumParameters LoopControlParams[FunctionControlCeiling];
|
||||||
EnumParameters SelectionControlParams[SelectControlCeiling];
|
EnumParameters SelectionControlParams[SelectControlCeiling];
|
||||||
EnumParameters FunctionControlParams[FunctionControlCeiling];
|
EnumParameters FunctionControlParams[FunctionControlCeiling];
|
||||||
|
EnumParameters MemoryAccessParams[MemoryAccessCeiling];
|
||||||
|
|
||||||
// Set up all the parameterizing descriptions of the opcodes, operands, etc.
|
// Set up all the parameterizing descriptions of the opcodes, operands, etc.
|
||||||
void Parameterize()
|
void Parameterize()
|
||||||
|
@ -1400,7 +1507,7 @@ void Parameterize()
|
||||||
OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true);
|
OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true);
|
||||||
OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true);
|
OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true);
|
||||||
OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true);
|
OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true);
|
||||||
OperandClassParams[OperandMemoryAccess].set(0, MemoryAccessString, nullptr, true);
|
OperandClassParams[OperandMemoryAccess].set(MemoryAccessCeiling, MemoryAccessString, MemoryAccessParams, true);
|
||||||
OperandClassParams[OperandScope].set(0, ScopeString, nullptr);
|
OperandClassParams[OperandScope].set(0, ScopeString, nullptr);
|
||||||
OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr);
|
OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr);
|
||||||
OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr);
|
OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr);
|
||||||
|
@ -1522,10 +1629,14 @@ void Parameterize()
|
||||||
|
|
||||||
InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
|
InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
|
||||||
InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
|
InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
|
||||||
|
InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true);
|
||||||
|
InstructionDesc[OpLoad].operands.push(OperandId, "", true);
|
||||||
|
|
||||||
InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'");
|
InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'");
|
||||||
InstructionDesc[OpStore].operands.push(OperandId, "'Object'");
|
InstructionDesc[OpStore].operands.push(OperandId, "'Object'");
|
||||||
InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true);
|
InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true);
|
||||||
|
InstructionDesc[OpStore].operands.push(OperandLiteralNumber, "", true);
|
||||||
|
InstructionDesc[OpStore].operands.push(OperandId, "", true);
|
||||||
|
|
||||||
InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'");
|
InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'");
|
||||||
|
|
||||||
|
@ -2566,6 +2677,42 @@ void Parameterize()
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
|
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
|
||||||
|
|
||||||
|
InstructionDesc[OpTypeAccelerationStructureNV].setResultAndType(true, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'NV Acceleration Structure'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'");
|
||||||
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
|
||||||
|
InstructionDesc[OpTraceNV].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'");
|
||||||
|
InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'");
|
||||||
|
|
||||||
|
InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpTerminateRayNV].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index");
|
||||||
|
InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID");
|
||||||
|
InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
|
||||||
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
|
||||||
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'");
|
||||||
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coarse'");
|
||||||
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandImageOperands, "", true);
|
||||||
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandVariableIds, "", true);
|
||||||
|
|
||||||
|
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'");
|
||||||
|
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2018 The Khronos Group Inc.
|
// Copyright (c) 2014-2019 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and/or associated documentation files (the "Materials"),
|
// of this software and/or associated documentation files (the "Materials"),
|
||||||
|
@ -26,13 +26,16 @@
|
||||||
// the Binary Section of the SPIR-V specification.
|
// the Binary Section of the SPIR-V specification.
|
||||||
|
|
||||||
// Enumeration tokens for SPIR-V, in various styles:
|
// Enumeration tokens for SPIR-V, in various styles:
|
||||||
// C, C++, C++11, JSON, Lua, Python
|
// C, C++, C++11, JSON, Lua, Python, C#, D
|
||||||
//
|
//
|
||||||
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||||
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||||
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
|
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
|
||||||
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
|
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
|
||||||
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
|
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
|
||||||
|
// - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
||||||
|
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||||
|
// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
||||||
//
|
//
|
||||||
// Some tokens act like mask values, which can be OR'd together,
|
// Some tokens act like mask values, which can be OR'd together,
|
||||||
// while others are mutually exclusive. The mask-like ones have
|
// while others are mutually exclusive. The mask-like ones have
|
||||||
|
@ -47,11 +50,11 @@ namespace spv {
|
||||||
typedef unsigned int Id;
|
typedef unsigned int Id;
|
||||||
|
|
||||||
#define SPV_VERSION 0x10300
|
#define SPV_VERSION 0x10300
|
||||||
#define SPV_REVISION 1
|
#define SPV_REVISION 6
|
||||||
|
|
||||||
static const unsigned int MagicNumber = 0x07230203;
|
static const unsigned int MagicNumber = 0x07230203;
|
||||||
static const unsigned int Version = 0x00010300;
|
static const unsigned int Version = 0x00010300;
|
||||||
static const unsigned int Revision = 1;
|
static const unsigned int Revision = 6;
|
||||||
static const unsigned int OpCodeMask = 0xffff;
|
static const unsigned int OpCodeMask = 0xffff;
|
||||||
static const unsigned int WordCountShift = 16;
|
static const unsigned int WordCountShift = 16;
|
||||||
|
|
||||||
|
@ -73,6 +76,14 @@ enum ExecutionModel {
|
||||||
ExecutionModelFragment = 4,
|
ExecutionModelFragment = 4,
|
||||||
ExecutionModelGLCompute = 5,
|
ExecutionModelGLCompute = 5,
|
||||||
ExecutionModelKernel = 6,
|
ExecutionModelKernel = 6,
|
||||||
|
ExecutionModelTaskNV = 5267,
|
||||||
|
ExecutionModelMeshNV = 5268,
|
||||||
|
ExecutionModelRayGenerationNV = 5313,
|
||||||
|
ExecutionModelIntersectionNV = 5314,
|
||||||
|
ExecutionModelAnyHitNV = 5315,
|
||||||
|
ExecutionModelClosestHitNV = 5316,
|
||||||
|
ExecutionModelMissNV = 5317,
|
||||||
|
ExecutionModelCallableNV = 5318,
|
||||||
ExecutionModelMax = 0x7fffffff,
|
ExecutionModelMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,6 +91,7 @@ enum AddressingModel {
|
||||||
AddressingModelLogical = 0,
|
AddressingModelLogical = 0,
|
||||||
AddressingModelPhysical32 = 1,
|
AddressingModelPhysical32 = 1,
|
||||||
AddressingModelPhysical64 = 2,
|
AddressingModelPhysical64 = 2,
|
||||||
|
AddressingModelPhysicalStorageBuffer64EXT = 5348,
|
||||||
AddressingModelMax = 0x7fffffff,
|
AddressingModelMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,6 +99,7 @@ enum MemoryModel {
|
||||||
MemoryModelSimple = 0,
|
MemoryModelSimple = 0,
|
||||||
MemoryModelGLSL450 = 1,
|
MemoryModelGLSL450 = 1,
|
||||||
MemoryModelOpenCL = 2,
|
MemoryModelOpenCL = 2,
|
||||||
|
MemoryModelVulkanKHR = 3,
|
||||||
MemoryModelMax = 0x7fffffff,
|
MemoryModelMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,7 +143,17 @@ enum ExecutionMode {
|
||||||
ExecutionModeLocalSizeId = 38,
|
ExecutionModeLocalSizeId = 38,
|
||||||
ExecutionModeLocalSizeHintId = 39,
|
ExecutionModeLocalSizeHintId = 39,
|
||||||
ExecutionModePostDepthCoverage = 4446,
|
ExecutionModePostDepthCoverage = 4446,
|
||||||
|
ExecutionModeDenormPreserve = 4459,
|
||||||
|
ExecutionModeDenormFlushToZero = 4460,
|
||||||
|
ExecutionModeSignedZeroInfNanPreserve = 4461,
|
||||||
|
ExecutionModeRoundingModeRTE = 4462,
|
||||||
|
ExecutionModeRoundingModeRTZ = 4463,
|
||||||
ExecutionModeStencilRefReplacingEXT = 5027,
|
ExecutionModeStencilRefReplacingEXT = 5027,
|
||||||
|
ExecutionModeOutputLinesNV = 5269,
|
||||||
|
ExecutionModeOutputPrimitivesNV = 5270,
|
||||||
|
ExecutionModeDerivativeGroupQuadsNV = 5289,
|
||||||
|
ExecutionModeDerivativeGroupLinearNV = 5290,
|
||||||
|
ExecutionModeOutputTrianglesNV = 5298,
|
||||||
ExecutionModeMax = 0x7fffffff,
|
ExecutionModeMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,6 +171,13 @@ enum StorageClass {
|
||||||
StorageClassAtomicCounter = 10,
|
StorageClassAtomicCounter = 10,
|
||||||
StorageClassImage = 11,
|
StorageClassImage = 11,
|
||||||
StorageClassStorageBuffer = 12,
|
StorageClassStorageBuffer = 12,
|
||||||
|
StorageClassCallableDataNV = 5328,
|
||||||
|
StorageClassIncomingCallableDataNV = 5329,
|
||||||
|
StorageClassRayPayloadNV = 5338,
|
||||||
|
StorageClassHitAttributeNV = 5339,
|
||||||
|
StorageClassIncomingRayPayloadNV = 5342,
|
||||||
|
StorageClassShaderRecordBufferNV = 5343,
|
||||||
|
StorageClassPhysicalStorageBufferEXT = 5349,
|
||||||
StorageClassMax = 0x7fffffff,
|
StorageClassMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -275,6 +305,10 @@ enum ImageOperandsShift {
|
||||||
ImageOperandsConstOffsetsShift = 5,
|
ImageOperandsConstOffsetsShift = 5,
|
||||||
ImageOperandsSampleShift = 6,
|
ImageOperandsSampleShift = 6,
|
||||||
ImageOperandsMinLodShift = 7,
|
ImageOperandsMinLodShift = 7,
|
||||||
|
ImageOperandsMakeTexelAvailableKHRShift = 8,
|
||||||
|
ImageOperandsMakeTexelVisibleKHRShift = 9,
|
||||||
|
ImageOperandsNonPrivateTexelKHRShift = 10,
|
||||||
|
ImageOperandsVolatileTexelKHRShift = 11,
|
||||||
ImageOperandsMax = 0x7fffffff,
|
ImageOperandsMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -288,6 +322,10 @@ enum ImageOperandsMask {
|
||||||
ImageOperandsConstOffsetsMask = 0x00000020,
|
ImageOperandsConstOffsetsMask = 0x00000020,
|
||||||
ImageOperandsSampleMask = 0x00000040,
|
ImageOperandsSampleMask = 0x00000040,
|
||||||
ImageOperandsMinLodMask = 0x00000080,
|
ImageOperandsMinLodMask = 0x00000080,
|
||||||
|
ImageOperandsMakeTexelAvailableKHRMask = 0x00000100,
|
||||||
|
ImageOperandsMakeTexelVisibleKHRMask = 0x00000200,
|
||||||
|
ImageOperandsNonPrivateTexelKHRMask = 0x00000400,
|
||||||
|
ImageOperandsVolatileTexelKHRMask = 0x00000800,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FPFastMathModeShift {
|
enum FPFastMathModeShift {
|
||||||
|
@ -388,12 +426,20 @@ enum Decoration {
|
||||||
DecorationMaxByteOffset = 45,
|
DecorationMaxByteOffset = 45,
|
||||||
DecorationAlignmentId = 46,
|
DecorationAlignmentId = 46,
|
||||||
DecorationMaxByteOffsetId = 47,
|
DecorationMaxByteOffsetId = 47,
|
||||||
|
DecorationNoSignedWrap = 4469,
|
||||||
|
DecorationNoUnsignedWrap = 4470,
|
||||||
DecorationExplicitInterpAMD = 4999,
|
DecorationExplicitInterpAMD = 4999,
|
||||||
DecorationOverrideCoverageNV = 5248,
|
DecorationOverrideCoverageNV = 5248,
|
||||||
DecorationPassthroughNV = 5250,
|
DecorationPassthroughNV = 5250,
|
||||||
DecorationViewportRelativeNV = 5252,
|
DecorationViewportRelativeNV = 5252,
|
||||||
DecorationSecondaryViewportRelativeNV = 5256,
|
DecorationSecondaryViewportRelativeNV = 5256,
|
||||||
|
DecorationPerPrimitiveNV = 5271,
|
||||||
|
DecorationPerViewNV = 5272,
|
||||||
|
DecorationPerTaskNV = 5273,
|
||||||
|
DecorationPerVertexNV = 5285,
|
||||||
DecorationNonUniformEXT = 5300,
|
DecorationNonUniformEXT = 5300,
|
||||||
|
DecorationRestrictPointerEXT = 5355,
|
||||||
|
DecorationAliasedPointerEXT = 5356,
|
||||||
DecorationHlslCounterBufferGOOGLE = 5634,
|
DecorationHlslCounterBufferGOOGLE = 5634,
|
||||||
DecorationHlslSemanticGOOGLE = 5635,
|
DecorationHlslSemanticGOOGLE = 5635,
|
||||||
DecorationMax = 0x7fffffff,
|
DecorationMax = 0x7fffffff,
|
||||||
|
@ -470,6 +516,34 @@ enum BuiltIn {
|
||||||
BuiltInPositionPerViewNV = 5261,
|
BuiltInPositionPerViewNV = 5261,
|
||||||
BuiltInViewportMaskPerViewNV = 5262,
|
BuiltInViewportMaskPerViewNV = 5262,
|
||||||
BuiltInFullyCoveredEXT = 5264,
|
BuiltInFullyCoveredEXT = 5264,
|
||||||
|
BuiltInTaskCountNV = 5274,
|
||||||
|
BuiltInPrimitiveCountNV = 5275,
|
||||||
|
BuiltInPrimitiveIndicesNV = 5276,
|
||||||
|
BuiltInClipDistancePerViewNV = 5277,
|
||||||
|
BuiltInCullDistancePerViewNV = 5278,
|
||||||
|
BuiltInLayerPerViewNV = 5279,
|
||||||
|
BuiltInMeshViewCountNV = 5280,
|
||||||
|
BuiltInMeshViewIndicesNV = 5281,
|
||||||
|
BuiltInBaryCoordNV = 5286,
|
||||||
|
BuiltInBaryCoordNoPerspNV = 5287,
|
||||||
|
BuiltInFragSizeEXT = 5292,
|
||||||
|
BuiltInFragmentSizeNV = 5292,
|
||||||
|
BuiltInFragInvocationCountEXT = 5293,
|
||||||
|
BuiltInInvocationsPerPixelNV = 5293,
|
||||||
|
BuiltInLaunchIdNV = 5319,
|
||||||
|
BuiltInLaunchSizeNV = 5320,
|
||||||
|
BuiltInWorldRayOriginNV = 5321,
|
||||||
|
BuiltInWorldRayDirectionNV = 5322,
|
||||||
|
BuiltInObjectRayOriginNV = 5323,
|
||||||
|
BuiltInObjectRayDirectionNV = 5324,
|
||||||
|
BuiltInRayTminNV = 5325,
|
||||||
|
BuiltInRayTmaxNV = 5326,
|
||||||
|
BuiltInInstanceCustomIndexNV = 5327,
|
||||||
|
BuiltInObjectToWorldNV = 5330,
|
||||||
|
BuiltInWorldToObjectNV = 5331,
|
||||||
|
BuiltInHitTNV = 5332,
|
||||||
|
BuiltInHitKindNV = 5333,
|
||||||
|
BuiltInIncomingRayFlagsNV = 5351,
|
||||||
BuiltInMax = 0x7fffffff,
|
BuiltInMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -528,6 +602,9 @@ enum MemorySemanticsShift {
|
||||||
MemorySemanticsCrossWorkgroupMemoryShift = 9,
|
MemorySemanticsCrossWorkgroupMemoryShift = 9,
|
||||||
MemorySemanticsAtomicCounterMemoryShift = 10,
|
MemorySemanticsAtomicCounterMemoryShift = 10,
|
||||||
MemorySemanticsImageMemoryShift = 11,
|
MemorySemanticsImageMemoryShift = 11,
|
||||||
|
MemorySemanticsOutputMemoryKHRShift = 12,
|
||||||
|
MemorySemanticsMakeAvailableKHRShift = 13,
|
||||||
|
MemorySemanticsMakeVisibleKHRShift = 14,
|
||||||
MemorySemanticsMax = 0x7fffffff,
|
MemorySemanticsMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -543,12 +620,18 @@ enum MemorySemanticsMask {
|
||||||
MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
|
MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
|
||||||
MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
|
MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
|
||||||
MemorySemanticsImageMemoryMask = 0x00000800,
|
MemorySemanticsImageMemoryMask = 0x00000800,
|
||||||
|
MemorySemanticsOutputMemoryKHRMask = 0x00001000,
|
||||||
|
MemorySemanticsMakeAvailableKHRMask = 0x00002000,
|
||||||
|
MemorySemanticsMakeVisibleKHRMask = 0x00004000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MemoryAccessShift {
|
enum MemoryAccessShift {
|
||||||
MemoryAccessVolatileShift = 0,
|
MemoryAccessVolatileShift = 0,
|
||||||
MemoryAccessAlignedShift = 1,
|
MemoryAccessAlignedShift = 1,
|
||||||
MemoryAccessNontemporalShift = 2,
|
MemoryAccessNontemporalShift = 2,
|
||||||
|
MemoryAccessMakePointerAvailableKHRShift = 3,
|
||||||
|
MemoryAccessMakePointerVisibleKHRShift = 4,
|
||||||
|
MemoryAccessNonPrivatePointerKHRShift = 5,
|
||||||
MemoryAccessMax = 0x7fffffff,
|
MemoryAccessMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -557,6 +640,9 @@ enum MemoryAccessMask {
|
||||||
MemoryAccessVolatileMask = 0x00000001,
|
MemoryAccessVolatileMask = 0x00000001,
|
||||||
MemoryAccessAlignedMask = 0x00000002,
|
MemoryAccessAlignedMask = 0x00000002,
|
||||||
MemoryAccessNontemporalMask = 0x00000004,
|
MemoryAccessNontemporalMask = 0x00000004,
|
||||||
|
MemoryAccessMakePointerAvailableKHRMask = 0x00000008,
|
||||||
|
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||||
|
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Scope {
|
enum Scope {
|
||||||
|
@ -565,6 +651,7 @@ enum Scope {
|
||||||
ScopeWorkgroup = 2,
|
ScopeWorkgroup = 2,
|
||||||
ScopeSubgroup = 3,
|
ScopeSubgroup = 3,
|
||||||
ScopeInvocation = 4,
|
ScopeInvocation = 4,
|
||||||
|
ScopeQueueFamilyKHR = 5,
|
||||||
ScopeMax = 0x7fffffff,
|
ScopeMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -682,6 +769,11 @@ enum Capability {
|
||||||
CapabilityStorageBuffer8BitAccess = 4448,
|
CapabilityStorageBuffer8BitAccess = 4448,
|
||||||
CapabilityUniformAndStorageBuffer8BitAccess = 4449,
|
CapabilityUniformAndStorageBuffer8BitAccess = 4449,
|
||||||
CapabilityStoragePushConstant8 = 4450,
|
CapabilityStoragePushConstant8 = 4450,
|
||||||
|
CapabilityDenormPreserve = 4464,
|
||||||
|
CapabilityDenormFlushToZero = 4465,
|
||||||
|
CapabilitySignedZeroInfNanPreserve = 4466,
|
||||||
|
CapabilityRoundingModeRTE = 4467,
|
||||||
|
CapabilityRoundingModeRTZ = 4468,
|
||||||
CapabilityFloat16ImageAMD = 5008,
|
CapabilityFloat16ImageAMD = 5008,
|
||||||
CapabilityImageGatherBiasLodAMD = 5009,
|
CapabilityImageGatherBiasLodAMD = 5009,
|
||||||
CapabilityFragmentMaskAMD = 5010,
|
CapabilityFragmentMaskAMD = 5010,
|
||||||
|
@ -695,6 +787,12 @@ enum Capability {
|
||||||
CapabilityShaderStereoViewNV = 5259,
|
CapabilityShaderStereoViewNV = 5259,
|
||||||
CapabilityPerViewAttributesNV = 5260,
|
CapabilityPerViewAttributesNV = 5260,
|
||||||
CapabilityFragmentFullyCoveredEXT = 5265,
|
CapabilityFragmentFullyCoveredEXT = 5265,
|
||||||
|
CapabilityMeshShadingNV = 5266,
|
||||||
|
CapabilityImageFootprintNV = 5282,
|
||||||
|
CapabilityFragmentBarycentricNV = 5284,
|
||||||
|
CapabilityComputeDerivativeGroupQuadsNV = 5288,
|
||||||
|
CapabilityFragmentDensityEXT = 5291,
|
||||||
|
CapabilityShadingRateNV = 5291,
|
||||||
CapabilityGroupNonUniformPartitionedNV = 5297,
|
CapabilityGroupNonUniformPartitionedNV = 5297,
|
||||||
CapabilityShaderNonUniformEXT = 5301,
|
CapabilityShaderNonUniformEXT = 5301,
|
||||||
CapabilityRuntimeDescriptorArrayEXT = 5302,
|
CapabilityRuntimeDescriptorArrayEXT = 5302,
|
||||||
|
@ -708,6 +806,11 @@ enum Capability {
|
||||||
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
|
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
|
||||||
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
|
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
|
||||||
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
||||||
|
CapabilityRayTracingNV = 5340,
|
||||||
|
CapabilityVulkanMemoryModelKHR = 5345,
|
||||||
|
CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
|
||||||
|
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
|
||||||
|
CapabilityComputeDerivativeGroupLinearNV = 5350,
|
||||||
CapabilitySubgroupShuffleINTEL = 5568,
|
CapabilitySubgroupShuffleINTEL = 5568,
|
||||||
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||||
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||||
|
@ -1071,7 +1174,15 @@ enum Op {
|
||||||
OpGroupSMaxNonUniformAMD = 5007,
|
OpGroupSMaxNonUniformAMD = 5007,
|
||||||
OpFragmentMaskFetchAMD = 5011,
|
OpFragmentMaskFetchAMD = 5011,
|
||||||
OpFragmentFetchAMD = 5012,
|
OpFragmentFetchAMD = 5012,
|
||||||
|
OpImageSampleFootprintNV = 5283,
|
||||||
OpGroupNonUniformPartitionNV = 5296,
|
OpGroupNonUniformPartitionNV = 5296,
|
||||||
|
OpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||||
|
OpReportIntersectionNV = 5334,
|
||||||
|
OpIgnoreIntersectionNV = 5335,
|
||||||
|
OpTerminateRayNV = 5336,
|
||||||
|
OpTraceNV = 5337,
|
||||||
|
OpTypeAccelerationStructureNV = 5341,
|
||||||
|
OpExecuteCallableNV = 5344,
|
||||||
OpSubgroupShuffleINTEL = 5571,
|
OpSubgroupShuffleINTEL = 5571,
|
||||||
OpSubgroupShuffleDownINTEL = 5572,
|
OpSubgroupShuffleDownINTEL = 5572,
|
||||||
OpSubgroupShuffleUpINTEL = 5573,
|
OpSubgroupShuffleUpINTEL = 5573,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014 LunarG, Inc.
|
// Copyright (C) 2014 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -79,6 +80,11 @@ const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||||
MemorySemanticsAtomicCounterMemoryMask |
|
MemorySemanticsAtomicCounterMemoryMask |
|
||||||
MemorySemanticsImageMemoryMask);
|
MemorySemanticsImageMemoryMask);
|
||||||
|
|
||||||
|
struct IdImmediate {
|
||||||
|
bool isId; // true if word is an Id, false if word is an immediate
|
||||||
|
unsigned word;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// SPIR-V IR instruction.
|
// SPIR-V IR instruction.
|
||||||
//
|
//
|
||||||
|
@ -88,8 +94,19 @@ public:
|
||||||
Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }
|
Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }
|
||||||
explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }
|
explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }
|
||||||
virtual ~Instruction() {}
|
virtual ~Instruction() {}
|
||||||
void addIdOperand(Id id) { operands.push_back(id); }
|
void addIdOperand(Id id) {
|
||||||
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
operands.push_back(id);
|
||||||
|
idOperand.push_back(true);
|
||||||
|
}
|
||||||
|
void addImmediateOperand(unsigned int immediate) {
|
||||||
|
operands.push_back(immediate);
|
||||||
|
idOperand.push_back(false);
|
||||||
|
}
|
||||||
|
void setImmediateOperand(unsigned idx, unsigned int immediate) {
|
||||||
|
assert(!idOperand[idx]);
|
||||||
|
operands[idx] = immediate;
|
||||||
|
}
|
||||||
|
|
||||||
void addStringOperand(const char* str)
|
void addStringOperand(const char* str)
|
||||||
{
|
{
|
||||||
unsigned int word;
|
unsigned int word;
|
||||||
|
@ -116,14 +133,25 @@ public:
|
||||||
addImmediateOperand(word);
|
addImmediateOperand(word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool isIdOperand(int op) const { return idOperand[op]; }
|
||||||
void setBlock(Block* b) { block = b; }
|
void setBlock(Block* b) { block = b; }
|
||||||
Block* getBlock() const { return block; }
|
Block* getBlock() const { return block; }
|
||||||
Op getOpCode() const { return opCode; }
|
Op getOpCode() const { return opCode; }
|
||||||
int getNumOperands() const { return (int)operands.size(); }
|
int getNumOperands() const
|
||||||
|
{
|
||||||
|
assert(operands.size() == idOperand.size());
|
||||||
|
return (int)operands.size();
|
||||||
|
}
|
||||||
Id getResultId() const { return resultId; }
|
Id getResultId() const { return resultId; }
|
||||||
Id getTypeId() const { return typeId; }
|
Id getTypeId() const { return typeId; }
|
||||||
Id getIdOperand(int op) const { return operands[op]; }
|
Id getIdOperand(int op) const {
|
||||||
unsigned int getImmediateOperand(int op) const { return operands[op]; }
|
assert(idOperand[op]);
|
||||||
|
return operands[op];
|
||||||
|
}
|
||||||
|
unsigned int getImmediateOperand(int op) const {
|
||||||
|
assert(!idOperand[op]);
|
||||||
|
return operands[op];
|
||||||
|
}
|
||||||
|
|
||||||
// Write out the binary form.
|
// Write out the binary form.
|
||||||
void dump(std::vector<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
@ -153,7 +181,8 @@ protected:
|
||||||
Id resultId;
|
Id resultId;
|
||||||
Id typeId;
|
Id typeId;
|
||||||
Op opCode;
|
Op opCode;
|
||||||
std::vector<Id> operands;
|
std::vector<Id> operands; // operands, both <id> and immediates (both are unsigned int)
|
||||||
|
std::vector<bool> idOperand; // true for operands that are <id>, false for immediates
|
||||||
Block* block;
|
Block* block;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,6 +208,7 @@ public:
|
||||||
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
||||||
return instructions;
|
return instructions;
|
||||||
}
|
}
|
||||||
|
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
|
||||||
void setUnreachable() { unreachable = true; }
|
void setUnreachable() { unreachable = true; }
|
||||||
bool isUnreachable() const { return unreachable; }
|
bool isUnreachable() const { return unreachable; }
|
||||||
// Returns the block's merge instruction, if one exists (otherwise null).
|
// Returns the block's merge instruction, if one exists (otherwise null).
|
||||||
|
@ -331,7 +361,9 @@ public:
|
||||||
|
|
||||||
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
||||||
const std::vector<Function*>& getFunctions() const { return functions; }
|
const std::vector<Function*>& getFunctions() const { return functions; }
|
||||||
spv::Id getTypeId(Id resultId) const { return idToInstruction[resultId]->getTypeId(); }
|
spv::Id getTypeId(Id resultId) const {
|
||||||
|
return idToInstruction[resultId] == nullptr ? NoType : idToInstruction[resultId]->getTypeId();
|
||||||
|
}
|
||||||
StorageClass getStorageClass(Id typeId) const
|
StorageClass getStorageClass(Id typeId) const
|
||||||
{
|
{
|
||||||
assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);
|
assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);
|
||||||
|
|
|
@ -89,26 +89,26 @@ static const TBuiltInResource DefaultTBuiltInResource = {
|
||||||
/* .MaxCullDistances = */ 8,
|
/* .MaxCullDistances = */ 8,
|
||||||
/* .MaxCombinedClipAndCullDistances = */ 8,
|
/* .MaxCombinedClipAndCullDistances = */ 8,
|
||||||
/* .MaxSamples = */ 4,
|
/* .MaxSamples = */ 4,
|
||||||
// /* .maxMeshOutputVerticesNV = */ 256,
|
/* .maxMeshOutputVerticesNV = */ 256,
|
||||||
// /* .maxMeshOutputPrimitivesNV = */ 512,
|
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||||
// /* .maxMeshWorkGroupSizeX_NV = */ 32,
|
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||||
// /* .maxMeshWorkGroupSizeY_NV = */ 1,
|
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||||
// /* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||||
// /* .maxTaskWorkGroupSizeX_NV = */ 32,
|
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||||
// /* .maxTaskWorkGroupSizeY_NV = */ 1,
|
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||||
// /* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||||
// /* .maxMeshViewCountNV = */ 4,
|
/* .maxMeshViewCountNV = */ 4,
|
||||||
|
|
||||||
/* .limits = */ {
|
/* .limits = */ {
|
||||||
/* .nonInductiveForLoops = */ 1,
|
/* .nonInductiveForLoops = */ 1,
|
||||||
/* .whileLoops = */ 1,
|
/* .whileLoops = */ 1,
|
||||||
/* .doWhileLoops = */ 1,
|
/* .doWhileLoops = */ 1,
|
||||||
/* .generalUniformIndexing = */ 1,
|
/* .generalUniformIndexing = */ 1,
|
||||||
/* .generalAttributeMatrixVectorIndexing = */ 1,
|
/* .generalAttributeMatrixVectorIndexing = */ 1,
|
||||||
/* .generalVaryingIndexing = */ 1,
|
/* .generalVaryingIndexing = */ 1,
|
||||||
/* .generalSamplerIndexing = */ 1,
|
/* .generalSamplerIndexing = */ 1,
|
||||||
/* .generalVariableIndexing = */ 1,
|
/* .generalVariableIndexing = */ 1,
|
||||||
/* .generalConstantMatrixVectorIndexing = */ 1,
|
/* .generalConstantMatrixVectorIndexing = */ 1,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue