Updated glslang.

This commit is contained in:
Branimir Karadžić 2017-07-07 21:19:36 -07:00
parent f27526d7e2
commit bdea8d2ce6
53 changed files with 4412 additions and 3971 deletions

View File

@ -6,8 +6,4 @@ tags
TAGS
build/
Test/localResults/
Test/multiThread.out
Test/singleThread.out
Test/vert.spv
Test/frag.spv
External/googletest

View File

@ -6,6 +6,11 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Adhere to GNU filesystem layout conventions
include(GNUInstallDirs)
option(SKIP_GLSLANG_INSTALL "Skip installation" ${SKIP_GLSLANG_INSTALL})
if(NOT ${SKIP_GLSLANG_INSTALL})
set(ENABLE_GLSLANG_INSTALL ON)
endif()
option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON)
option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON)

View File

@ -1,11 +1,14 @@
set(SOURCES InitializeDll.cpp InitializeDll.h)
add_library(OGLCompiler STATIC ${SOURCES})
set_property(TARGET OGLCompiler PROPERTY FOLDER glslang POSITION_INDEPENDENT_CODE ON)
set_property(TARGET OGLCompiler PROPERTY FOLDER glslang)
set_property(TARGET OGLCompiler PROPERTY POSITION_INDEPENDENT_CODE ON)
if(WIN32)
source_group("Source" FILES ${SOURCES})
endif(WIN32)
install(TARGETS OGLCompiler
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS OGLCompiler
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_GLSLANG_INSTALL)

View File

@ -40,18 +40,22 @@ if(ENABLE_NV_EXTENSIONS)
endif(ENABLE_NV_EXTENSIONS)
add_library(SPIRV STATIC ${SOURCES} ${HEADERS})
set_property(TARGET SPIRV PROPERTY FOLDER glslang POSITION_INDEPENDENT_CODE ON)
set_property(TARGET SPIRV PROPERTY FOLDER glslang)
set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(SPIRV glslang)
add_library(SPVRemapper STATIC ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
set_property(TARGET SPVRemapper PROPERTY FOLDER glslang POSITION_INDEPENDENT_CODE ON)
set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON)
if(WIN32)
source_group("Source" FILES ${SOURCES} ${HEADERS})
source_group("Source" FILES ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
endif(WIN32)
install(TARGETS SPIRV SPVRemapper
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS SPIRV SPVRemapper
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SPIRV/)
install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SPIRV/)
endif(ENABLE_GLSLANG_INSTALL)

View File

@ -32,7 +32,7 @@ enum Op;
enum Capability;
static const int GLSLextKHRVersion = 100;
static const int GLSLextKHRRevision = 1;
static const int GLSLextKHRRevision = 2;
static const char* const E_SPV_KHR_shader_ballot = "SPV_KHR_shader_ballot";
static const char* const E_SPV_KHR_subgroup_vote = "SPV_KHR_subgroup_vote";
@ -41,5 +41,6 @@ static const char* const E_SPV_KHR_multiview = "SPV_KHR_multi
static const char* const E_SPV_KHR_shader_draw_parameters = "SPV_KHR_shader_draw_parameters";
static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit_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_post_depth_coverage = "SPV_KHR_post_depth_coverage";
#endif // #ifndef GLSLextKHR_H

View File

@ -122,6 +122,7 @@ protected:
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
spv::SelectionControlMask TranslateSelectionControl(glslang::TSelectionControl) const;
spv::LoopControlMask TranslateLoopControl(glslang::TLoopControl) const;
spv::StorageClass TranslateStorageClass(const glslang::TType&);
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
@ -741,6 +742,16 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
}
}
spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(glslang::TSelectionControl selectionControl) const
{
switch (selectionControl) {
case glslang::ESelectionControlNone: return spv::SelectionControlMaskNone;
case glslang::ESelectionControlFlatten: return spv::SelectionControlFlattenMask;
case glslang::ESelectionControlDontFlatten: return spv::SelectionControlDontFlattenMask;
default: return spv::SelectionControlMaskNone;
}
}
spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(glslang::TLoopControl loopControl) const
{
switch (loopControl) {
@ -980,6 +991,12 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
if (glslangIntermediate->getEarlyFragmentTests())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests);
if (glslangIntermediate->getPostDepthCoverage()) {
builder.addCapability(spv::CapabilitySampleMaskPostDepthCoverage);
builder.addExecutionMode(shaderEntry, spv::ExecutionModePostDepthCoverage);
builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
}
switch(glslangIntermediate->getDepth()) {
case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
@ -1935,8 +1952,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
return false;
}
// Instead, emit control flow...
// Instead, emit control flow...
// Don't handle results as temporaries, because there will be two names
// and better to leave SSA to later passes.
spv::Id result = (node->getBasicType() == glslang::EbtVoid)
@ -1946,8 +1962,11 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
// emit the condition before doing anything with selection
node->getCondition()->traverse(this);
// Selection control:
const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
// make an "if" based on the value created by the condition
spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), builder);
spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), control, builder);
// emit the "then" statement
if (node->getTrueBlock() != nullptr) {
@ -1985,6 +2004,9 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
node->getCondition()->traverse(this);
spv::Id selector = accessChainLoad(node->getCondition()->getAsTyped()->getType());
// Selection control:
const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
// browse the children to sort out code segments
int defaultSegment = -1;
std::vector<TIntermNode*> codeSegments;
@ -2010,7 +2032,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
// make the switch statement
std::vector<spv::Block*> segmentBlocks; // returned, as the blocks allocated in the call
builder.makeSwitch(selector, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
// emit all the code in the segments
breakForLoop.push(false);
@ -5701,7 +5723,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan
leftId = builder.createUnaryOp(spv::OpLogicalNot, boolTypeId, leftId);
// make an "if" based on the left value
spv::Builder::If ifBuilder(leftId, builder);
spv::Builder::If ifBuilder(leftId, spv::SelectionControlMaskNone, builder);
// emit right operand as the "then" part of the "if"
builder.clearAccessChain();

View File

@ -2009,9 +2009,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
}
// Comments in header
Builder::If::If(Id cond, Builder& gb) :
Builder::If::If(Id cond, unsigned int ctrl, Builder& gb) :
builder(gb),
condition(cond),
control(ctrl),
elseBlock(0)
{
function = &builder.getBuildPoint()->getParent();
@ -2052,7 +2053,7 @@ void Builder::If::makeEndIf()
// Go back to the headerBlock and make the flow control split
builder.setBuildPoint(headerBlock);
builder.createSelectionMerge(mergeBlock, SelectionControlMaskNone);
builder.createSelectionMerge(mergeBlock, control);
if (elseBlock)
builder.createConditionalBranch(condition, thenBlock, elseBlock);
else
@ -2064,7 +2065,7 @@ void Builder::If::makeEndIf()
}
// Comments in header
void Builder::makeSwitch(Id selector, int numSegments, const std::vector<int>& caseValues,
void Builder::makeSwitch(Id selector, unsigned int control, int numSegments, const std::vector<int>& caseValues,
const std::vector<int>& valueIndexToSegment, int defaultSegment,
std::vector<Block*>& segmentBlocks)
{
@ -2077,7 +2078,7 @@ void Builder::makeSwitch(Id selector, int numSegments, const std::vector<int>& c
Block* mergeBlock = new Block(getUniqueId(), function);
// make and insert the switch's selection-merge instruction
createSelectionMerge(mergeBlock, SelectionControlMaskNone);
createSelectionMerge(mergeBlock, control);
// make the switch instruction
Instruction* switchInst = new Instruction(NoResult, NoType, OpSwitch);

View File

@ -385,7 +385,7 @@ public:
// Helper to use for building nested control flow with if-then-else.
class If {
public:
If(Id condition, Builder& builder);
If(Id condition, unsigned int ctrl, Builder& builder);
~If() {}
void makeBeginElse();
@ -397,6 +397,7 @@ public:
Builder& builder;
Id condition;
unsigned int control;
Function* function;
Block* headerBlock;
Block* thenBlock;
@ -416,7 +417,7 @@ public:
// Returns the right set of basic blocks to start each code segment with, so that the caller's
// recursion stack can hold the memory for it.
//
void makeSwitch(Id condition, int numSegments, const std::vector<int>& caseValues,
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
// Add a branch to the innermost switch's merge block.

View File

@ -175,6 +175,7 @@ const char* ExecutionModeString(int mode)
case 31: return "ContractionOff";
case 32: return "Bad";
case 4446: return "PostDepthCoverage";
case ExecutionModeCeiling:
default: return "Bad";
}
@ -636,13 +637,15 @@ const char* SelectControlString(int cont)
}
}
const int LoopControlCeiling = 2;
const int LoopControlCeiling = 4;
const char* LoopControlString(int cont)
{
switch (cont) {
case 0: return "Unroll";
case 1: return "DontUnroll";
case 2: return "DependencyInfinite";
case 3: return "DependencyLength";
case LoopControlCeiling:
default: return "Bad";
@ -843,6 +846,7 @@ const char* CapabilityString(int info)
case 5009: return "ImageGatherBiasLodAMD";
#endif
case 4447: return "SampleMaskPostDepthCoverage";
#ifdef NV_EXTENSIONS
case 5251: return "GeometryShaderPassthroughNV";
case 5254: return "ShaderViewportIndexLayerNV";

View File

@ -47,11 +47,11 @@ namespace spv {
typedef unsigned int Id;
#define SPV_VERSION 0x10000
#define SPV_REVISION 10
#define SPV_REVISION 11
static const unsigned int MagicNumber = 0x07230203;
static const unsigned int Version = 0x00010000;
static const unsigned int Revision = 10;
static const unsigned int Revision = 11;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@ -122,6 +122,7 @@ enum ExecutionMode {
ExecutionModeOutputTriangleStrip = 29,
ExecutionModeVecTypeHint = 30,
ExecutionModeContractionOff = 31,
ExecutionModePostDepthCoverage = 4446,
ExecutionModeMax = 0x7fffffff,
};
@ -628,6 +629,7 @@ enum Capability {
CapabilityMultiView = 4439,
CapabilityVariablePointersStorageBuffer = 4441,
CapabilityVariablePointers = 4442,
CapabilitySampleMaskPostDepthCoverage = 4447,
CapabilitySampleMaskOverrideCoverageNV = 5249,
CapabilityGeometryShaderPassthroughNV = 5251,
CapabilityShaderViewportIndexLayerNV = 5254,

View File

@ -1,6 +1,7 @@
add_library(glslang-default-resource-limits
${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp)
set_property(TARGET glslang-default-resource-limits PROPERTY FOLDER glslang POSITION_INDEPENDENT_CODE ON)
set_property(TARGET glslang-default-resource-limits PROPERTY FOLDER glslang)
set_property(TARGET glslang-default-resource-limits PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(glslang-default-resource-limits
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
@ -37,8 +38,10 @@ if(WIN32)
source_group("Source" FILES ${SOURCES})
endif(WIN32)
install(TARGETS glslangValidator
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS glslangValidator
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS spirv-remap
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS spirv-remap
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif(ENABLE_GLSLANG_INSTALL)

View File

@ -186,6 +186,8 @@ void fooDeeparray()
yp = x; // ERROR, wrong size
}
layout(num_views = 2) in; // ERROR, no extension
void mwErr()
{
gl_ViewID_OVR; // ERROR, no extension
@ -193,6 +195,9 @@ void mwErr()
#extension GL_OVR_multiview : enable
layout(num_views = 2) uniform float mwUniform; // ERROR, must be global
layout(num_views = 2) in; // OK
void mwOk()
{
gl_ViewID_OVR;

View File

@ -43,10 +43,14 @@ ERROR: 0:172: 'std430' : requires the 'buffer' storage qualifier
ERROR: 0:175: '' : array size required
ERROR: 0:185: 'assign' : cannot convert from ' temp 4-element array of highp float' to ' temp 3-element array of highp float'
ERROR: 0:186: 'assign' : cannot convert from ' temp 3-element array of highp float' to ' temp 4-element array of highp float'
ERROR: 0:191: 'gl_ViewID_OVR' : required extension not requested: Possible extensions include:
ERROR: 0:189: 'num_views' : required extension not requested: Possible extensions include:
GL_OVR_multiview
GL_OVR_multiview2
ERROR: 45 compilation errors. No code generated.
ERROR: 0:193: 'gl_ViewID_OVR' : required extension not requested: Possible extensions include:
GL_OVR_multiview
GL_OVR_multiview2
ERROR: 0:198: 'num_views' : can only apply to a standalone qualifier
ERROR: 47 compilation errors. No code generated.
Shader version: 300
@ -293,14 +297,14 @@ ERROR: node is still EOpNull!
0:184 'y' ( temp 4-element array of highp float)
0:185 'xp' ( temp 3-element array of highp float)
0:186 'yp' ( temp 4-element array of highp float)
0:189 Function Definition: mwErr( ( global void)
0:189 Function Parameters:
0:191 Sequence
0:191 'gl_ViewID_OVR' ( in highp uint ViewIndex)
0:196 Function Definition: mwOk( ( global void)
0:196 Function Parameters:
0:198 Sequence
0:198 'gl_ViewID_OVR' ( in highp uint ViewIndex)
0:191 Function Definition: mwErr( ( global void)
0:191 Function Parameters:
0:193 Sequence
0:193 'gl_ViewID_OVR' ( in highp uint ViewIndex)
0:201 Function Definition: mwOk( ( global void)
0:201 Function Parameters:
0:203 Sequence
0:203 'gl_ViewID_OVR' ( in highp uint ViewIndex)
0:? Linker Objects
0:? 'm43' ( uniform highp 4X3 matrix of float)
0:? 'm33' ( uniform highp 3X3 matrix of float)
@ -335,6 +339,7 @@ ERROR: node is still EOpNull!
0:? 'Binst' (layout( column_major shared) uniform block{layout( column_major shared) uniform highp int a})
0:? 'Bfoo' ( global highp int)
0:? 'B430i' (layout( column_major std430) uniform block{layout( column_major std430 offset=0) uniform highp int a})
0:? 'mwUniform' ( uniform highp float)
0:? 'gl_VertexID' ( gl_VertexId highp int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
@ -494,6 +499,7 @@ ERROR: node is still EOpNull!
0:? 'Binst' (layout( column_major shared) uniform block{layout( column_major shared) uniform highp int a})
0:? 'Bfoo' ( global highp int)
0:? 'B430i' (layout( column_major std430) uniform block{layout( column_major std430 offset=0) uniform highp int a})
0:? 'mwUniform' ( uniform highp float)
0:? 'gl_VertexID' ( gl_VertexId highp int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)

View File

@ -90,7 +90,7 @@ gl_FragCoord origin is upper left
11(@PixelShaderFunction(vf4;): 2 Function None 9
10(input): 8(ptr) FunctionParameter
12: Label
SelectionMerge 16 None
SelectionMerge 16 DontFlatten
BranchConditional 14 15 16
15: Label
Branch 16

View File

@ -319,7 +319,7 @@ gl_FragCoord origin is upper left
48: 7(fvec4) Load 10(input)
49: 16(bvec4) FOrdEqual 47 48
50: 15(bool) All 49
SelectionMerge 52 None
SelectionMerge 52 Flatten
BranchConditional 50 51 52
51: Label
53: 7(fvec4) Load 10(input)

View File

@ -11,7 +11,8 @@ local_size = (1, 1, 1)
0:17 'inU1' ( in uint)
0:? Sequence
0:21 all ( temp bool)
0:21 'inF0' ( in float)
0:21 Convert float to bool ( temp bool)
0:21 'inF0' ( in float)
0:24 AtomicAdd ( temp void)
0:24 'gs_ua' ( shared uint)
0:24 'gs_ub' ( shared uint)
@ -92,7 +93,8 @@ local_size = (1, 1, 1)
0:51 'inU1' ( in 2-component vector of uint)
0:? Sequence
0:55 all ( temp bool)
0:55 'inF0' ( in 2-component vector of float)
0:55 Convert float to bool ( temp 2-component vector of bool)
0:55 'inF0' ( in 2-component vector of float)
0:58 AtomicAdd ( temp void)
0:58 'gs_ua2' ( shared 2-component vector of uint)
0:58 'gs_ub2' ( shared 2-component vector of uint)
@ -165,7 +167,8 @@ local_size = (1, 1, 1)
0:78 'inU1' ( in 3-component vector of uint)
0:? Sequence
0:82 all ( temp bool)
0:82 'inF0' ( in 3-component vector of float)
0:82 Convert float to bool ( temp 3-component vector of bool)
0:82 'inF0' ( in 3-component vector of float)
0:85 AtomicAdd ( temp void)
0:85 'gs_ua3' ( shared 3-component vector of uint)
0:85 'gs_ub3' ( shared 3-component vector of uint)
@ -239,7 +242,8 @@ local_size = (1, 1, 1)
0:105 'inU1' ( in 4-component vector of uint)
0:? Sequence
0:109 all ( temp bool)
0:109 'inF0' ( in 4-component vector of float)
0:109 Convert float to bool ( temp 4-component vector of bool)
0:109 'inF0' ( in 4-component vector of float)
0:112 AtomicAdd ( temp void)
0:112 'gs_ua4' ( shared 4-component vector of uint)
0:112 'gs_ub4' ( shared 4-component vector of uint)
@ -367,7 +371,8 @@ local_size = (1, 1, 1)
0:17 'inU1' ( in uint)
0:? Sequence
0:21 all ( temp bool)
0:21 'inF0' ( in float)
0:21 Convert float to bool ( temp bool)
0:21 'inF0' ( in float)
0:24 AtomicAdd ( temp void)
0:24 'gs_ua' ( shared uint)
0:24 'gs_ub' ( shared uint)
@ -448,7 +453,8 @@ local_size = (1, 1, 1)
0:51 'inU1' ( in 2-component vector of uint)
0:? Sequence
0:55 all ( temp bool)
0:55 'inF0' ( in 2-component vector of float)
0:55 Convert float to bool ( temp 2-component vector of bool)
0:55 'inF0' ( in 2-component vector of float)
0:58 AtomicAdd ( temp void)
0:58 'gs_ua2' ( shared 2-component vector of uint)
0:58 'gs_ub2' ( shared 2-component vector of uint)
@ -521,7 +527,8 @@ local_size = (1, 1, 1)
0:78 'inU1' ( in 3-component vector of uint)
0:? Sequence
0:82 all ( temp bool)
0:82 'inF0' ( in 3-component vector of float)
0:82 Convert float to bool ( temp 3-component vector of bool)
0:82 'inF0' ( in 3-component vector of float)
0:85 AtomicAdd ( temp void)
0:85 'gs_ua3' ( shared 3-component vector of uint)
0:85 'gs_ub3' ( shared 3-component vector of uint)
@ -595,7 +602,8 @@ local_size = (1, 1, 1)
0:105 'inU1' ( in 4-component vector of uint)
0:? Sequence
0:109 all ( temp bool)
0:109 'inF0' ( in 4-component vector of float)
0:109 Convert float to bool ( temp 4-component vector of bool)
0:109 'inF0' ( in 4-component vector of float)
0:112 AtomicAdd ( temp void)
0:112 'gs_ua4' ( shared 4-component vector of uint)
0:112 'gs_ub4' ( shared 4-component vector of uint)
@ -709,12 +717,12 @@ local_size = (1, 1, 1)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 255
// Id's are bound by 265
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint GLCompute 4 "ComputeShaderFunction" 227 230 233 237 240 243
EntryPoint GLCompute 4 "ComputeShaderFunction" 237 240 243 247 250 253
ExecutionMode 4 LocalSize 1 1 1
Source HLSL 500
Name 4 "ComputeShaderFunction"
@ -746,44 +754,44 @@ local_size = (1, 1, 1)
Name 55 "inF2"
Name 56 "inU0"
Name 57 "inU1"
Name 64 "gs_ua"
Name 65 "gs_ub"
Name 70 "out_u1"
Name 78 "gs_uc"
Name 107 "gs_ua2"
Name 108 "gs_ub2"
Name 111 "out_u2"
Name 119 "gs_uc2"
Name 148 "gs_ua3"
Name 149 "gs_ub3"
Name 152 "out_u3"
Name 160 "gs_uc3"
Name 188 "gs_ua4"
Name 189 "gs_ub4"
Name 192 "out_u4"
Name 200 "gs_uc4"
Name 225 "inF0"
Name 227 "inF0"
Name 229 "inF1"
Name 230 "inF1"
Name 232 "inF2"
Name 233 "inF2"
Name 235 "inU0"
Name 237 "inU0"
Name 239 "inU1"
Name 240 "inU1"
Name 243 "@entryPointOutput"
Name 244 "param"
Name 246 "param"
Name 248 "param"
Name 250 "param"
Name 252 "param"
Decorate 227(inF0) Location 0
Decorate 230(inF1) Location 1
Decorate 233(inF2) Location 2
Decorate 237(inU0) Location 3
Decorate 240(inU1) Location 4
Decorate 243(@entryPointOutput) Location 0
Name 66 "gs_ua"
Name 67 "gs_ub"
Name 72 "out_u1"
Name 80 "gs_uc"
Name 111 "gs_ua2"
Name 112 "gs_ub2"
Name 115 "out_u2"
Name 123 "gs_uc2"
Name 155 "gs_ua3"
Name 156 "gs_ub3"
Name 159 "out_u3"
Name 167 "gs_uc3"
Name 198 "gs_ua4"
Name 199 "gs_ub4"
Name 202 "out_u4"
Name 210 "gs_uc4"
Name 235 "inF0"
Name 237 "inF0"
Name 239 "inF1"
Name 240 "inF1"
Name 242 "inF2"
Name 243 "inF2"
Name 245 "inU0"
Name 247 "inU0"
Name 249 "inU1"
Name 250 "inU1"
Name 253 "@entryPointOutput"
Name 254 "param"
Name 256 "param"
Name 258 "param"
Name 260 "param"
Name 262 "param"
Decorate 237(inF0) Location 0
Decorate 240(inF1) Location 1
Decorate 243(inF2) Location 2
Decorate 247(inU0) Location 3
Decorate 250(inU1) Location 4
Decorate 253(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@ -808,75 +816,81 @@ local_size = (1, 1, 1)
51: TypePointer Function 50(ivec4)
52: TypeFunction 48(fvec4) 49(ptr) 49(ptr) 49(ptr) 51(ptr) 51(ptr)
61: TypeBool
63: TypePointer Workgroup 8(int)
64(gs_ua): 63(ptr) Variable Workgroup
65(gs_ub): 63(ptr) Variable Workgroup
67: 8(int) Constant 1
68: 8(int) Constant 0
78(gs_uc): 63(ptr) Variable Workgroup
99: 6(float) Constant 0
106: TypePointer Workgroup 26(ivec2)
107(gs_ua2): 106(ptr) Variable Workgroup
108(gs_ub2): 106(ptr) Variable Workgroup
119(gs_uc2): 106(ptr) Variable Workgroup
140: 6(float) Constant 1065353216
141: 6(float) Constant 1073741824
142: 24(fvec2) ConstantComposite 140 141
147: TypePointer Workgroup 38(ivec3)
148(gs_ua3): 147(ptr) Variable Workgroup
149(gs_ub3): 147(ptr) Variable Workgroup
160(gs_uc3): 147(ptr) Variable Workgroup
181: 6(float) Constant 1077936128
182: 36(fvec3) ConstantComposite 140 141 181
187: TypePointer Workgroup 50(ivec4)
188(gs_ua4): 187(ptr) Variable Workgroup
189(gs_ub4): 187(ptr) Variable Workgroup
200(gs_uc4): 187(ptr) Variable Workgroup
221: 6(float) Constant 1082130432
222: 48(fvec4) ConstantComposite 140 141 181 221
226: TypePointer Input 48(fvec4)
227(inF0): 226(ptr) Variable Input
230(inF1): 226(ptr) Variable Input
233(inF2): 226(ptr) Variable Input
236: TypePointer Input 50(ivec4)
237(inU0): 236(ptr) Variable Input
240(inU1): 236(ptr) Variable Input
242: TypePointer Output 48(fvec4)
243(@entryPointOutput): 242(ptr) Variable Output
62: 6(float) Constant 0
65: TypePointer Workgroup 8(int)
66(gs_ua): 65(ptr) Variable Workgroup
67(gs_ub): 65(ptr) Variable Workgroup
69: 8(int) Constant 1
70: 8(int) Constant 0
80(gs_uc): 65(ptr) Variable Workgroup
106: TypeVector 61(bool) 2
107: 24(fvec2) ConstantComposite 62 62
110: TypePointer Workgroup 26(ivec2)
111(gs_ua2): 110(ptr) Variable Workgroup
112(gs_ub2): 110(ptr) Variable Workgroup
123(gs_uc2): 110(ptr) Variable Workgroup
144: 6(float) Constant 1065353216
145: 6(float) Constant 1073741824
146: 24(fvec2) ConstantComposite 144 145
150: TypeVector 61(bool) 3
151: 36(fvec3) ConstantComposite 62 62 62
154: TypePointer Workgroup 38(ivec3)
155(gs_ua3): 154(ptr) Variable Workgroup
156(gs_ub3): 154(ptr) Variable Workgroup
167(gs_uc3): 154(ptr) Variable Workgroup
188: 6(float) Constant 1077936128
189: 36(fvec3) ConstantComposite 144 145 188
193: TypeVector 61(bool) 4
194: 48(fvec4) ConstantComposite 62 62 62 62
197: TypePointer Workgroup 50(ivec4)
198(gs_ua4): 197(ptr) Variable Workgroup
199(gs_ub4): 197(ptr) Variable Workgroup
210(gs_uc4): 197(ptr) Variable Workgroup
231: 6(float) Constant 1082130432
232: 48(fvec4) ConstantComposite 144 145 188 231
236: TypePointer Input 48(fvec4)
237(inF0): 236(ptr) Variable Input
240(inF1): 236(ptr) Variable Input
243(inF2): 236(ptr) Variable Input
246: TypePointer Input 50(ivec4)
247(inU0): 246(ptr) Variable Input
250(inU1): 246(ptr) Variable Input
252: TypePointer Output 48(fvec4)
253(@entryPointOutput): 252(ptr) Variable Output
4(ComputeShaderFunction): 2 Function None 3
5: Label
225(inF0): 49(ptr) Variable Function
229(inF1): 49(ptr) Variable Function
232(inF2): 49(ptr) Variable Function
235(inU0): 51(ptr) Variable Function
239(inU1): 51(ptr) Variable Function
244(param): 49(ptr) Variable Function
246(param): 49(ptr) Variable Function
248(param): 49(ptr) Variable Function
250(param): 51(ptr) Variable Function
252(param): 51(ptr) Variable Function
228: 48(fvec4) Load 227(inF0)
Store 225(inF0) 228
231: 48(fvec4) Load 230(inF1)
Store 229(inF1) 231
234: 48(fvec4) Load 233(inF2)
Store 232(inF2) 234
238: 50(ivec4) Load 237(inU0)
Store 235(inU0) 238
241: 50(ivec4) Load 240(inU1)
Store 239(inU1) 241
245: 48(fvec4) Load 225(inF0)
Store 244(param) 245
247: 48(fvec4) Load 229(inF1)
Store 246(param) 247
249: 48(fvec4) Load 232(inF2)
Store 248(param) 249
251: 50(ivec4) Load 235(inU0)
Store 250(param) 251
253: 50(ivec4) Load 239(inU1)
Store 252(param) 253
254: 48(fvec4) FunctionCall 58(@ComputeShaderFunction(vf4;vf4;vf4;vu4;vu4;) 244(param) 246(param) 248(param) 250(param) 252(param)
Store 243(@entryPointOutput) 254
235(inF0): 49(ptr) Variable Function
239(inF1): 49(ptr) Variable Function
242(inF2): 49(ptr) Variable Function
245(inU0): 51(ptr) Variable Function
249(inU1): 51(ptr) Variable Function
254(param): 49(ptr) Variable Function
256(param): 49(ptr) Variable Function
258(param): 49(ptr) Variable Function
260(param): 51(ptr) Variable Function
262(param): 51(ptr) Variable Function
238: 48(fvec4) Load 237(inF0)
Store 235(inF0) 238
241: 48(fvec4) Load 240(inF1)
Store 239(inF1) 241
244: 48(fvec4) Load 243(inF2)
Store 242(inF2) 244
248: 50(ivec4) Load 247(inU0)
Store 245(inU0) 248
251: 50(ivec4) Load 250(inU1)
Store 249(inU1) 251
255: 48(fvec4) Load 235(inF0)
Store 254(param) 255
257: 48(fvec4) Load 239(inF1)
Store 256(param) 257
259: 48(fvec4) Load 242(inF2)
Store 258(param) 259
261: 50(ivec4) Load 245(inU0)
Store 260(param) 261
263: 50(ivec4) Load 249(inU1)
Store 262(param) 263
264: 48(fvec4) FunctionCall 58(@ComputeShaderFunction(vf4;vf4;vf4;vu4;vu4;) 254(param) 256(param) 258(param) 260(param) 262(param)
Store 253(@entryPointOutput) 264
Return
FunctionEnd
16(ComputeShaderFunctionS(f1;f1;f1;u1;u1;): 6(float) Function None 10
@ -886,54 +900,55 @@ local_size = (1, 1, 1)
14(inU0): 9(ptr) FunctionParameter
15(inU1): 9(ptr) FunctionParameter
17: Label
70(out_u1): 9(ptr) Variable Function
72(out_u1): 9(ptr) Variable Function
60: 6(float) Load 11(inF0)
62: 61(bool) All 60
66: 8(int) Load 65(gs_ub)
69: 2 AtomicIAdd 64(gs_ua) 67 68 66
71: 8(int) Load 65(gs_ub)
72: 8(int) AtomicIAdd 64(gs_ua) 67 68 71
Store 70(out_u1) 72
73: 8(int) Load 65(gs_ub)
74: 2 AtomicAnd 64(gs_ua) 67 68 73
75: 8(int) Load 65(gs_ub)
76: 8(int) AtomicAnd 64(gs_ua) 67 68 75
Store 70(out_u1) 76
77: 8(int) Load 65(gs_ub)
79: 8(int) Load 78(gs_uc)
80: 8(int) AtomicCompareExchange 64(gs_ua) 67 68 68 79 77
Store 70(out_u1) 80
81: 8(int) Load 65(gs_ub)
82: 8(int) AtomicExchange 64(gs_ua) 67 68 81
Store 70(out_u1) 82
83: 8(int) Load 65(gs_ub)
84: 2 AtomicSMax 64(gs_ua) 67 68 83
85: 8(int) Load 65(gs_ub)
86: 8(int) AtomicUMax 64(gs_ua) 67 68 85
Store 70(out_u1) 86
87: 8(int) Load 65(gs_ub)
88: 2 AtomicSMin 64(gs_ua) 67 68 87
89: 8(int) Load 65(gs_ub)
90: 8(int) AtomicUMin 64(gs_ua) 67 68 89
Store 70(out_u1) 90
91: 8(int) Load 65(gs_ub)
92: 2 AtomicOr 64(gs_ua) 67 68 91
93: 8(int) Load 65(gs_ub)
94: 8(int) AtomicOr 64(gs_ua) 67 68 93
Store 70(out_u1) 94
95: 8(int) Load 65(gs_ub)
96: 2 AtomicXor 64(gs_ua) 67 68 95
97: 8(int) Load 65(gs_ub)
98: 8(int) AtomicXor 64(gs_ua) 67 68 97
Store 70(out_u1) 98
ReturnValue 99
63: 61(bool) FOrdNotEqual 60 62
64: 61(bool) All 63
68: 8(int) Load 67(gs_ub)
71: 2 AtomicIAdd 66(gs_ua) 69 70 68
73: 8(int) Load 67(gs_ub)
74: 8(int) AtomicIAdd 66(gs_ua) 69 70 73
Store 72(out_u1) 74
75: 8(int) Load 67(gs_ub)
76: 2 AtomicAnd 66(gs_ua) 69 70 75
77: 8(int) Load 67(gs_ub)
78: 8(int) AtomicAnd 66(gs_ua) 69 70 77
Store 72(out_u1) 78
79: 8(int) Load 67(gs_ub)
81: 8(int) Load 80(gs_uc)
82: 8(int) AtomicCompareExchange 66(gs_ua) 69 70 70 81 79
Store 72(out_u1) 82
83: 8(int) Load 67(gs_ub)
84: 8(int) AtomicExchange 66(gs_ua) 69 70 83
Store 72(out_u1) 84
85: 8(int) Load 67(gs_ub)
86: 2 AtomicSMax 66(gs_ua) 69 70 85
87: 8(int) Load 67(gs_ub)
88: 8(int) AtomicUMax 66(gs_ua) 69 70 87
Store 72(out_u1) 88
89: 8(int) Load 67(gs_ub)
90: 2 AtomicSMin 66(gs_ua) 69 70 89
91: 8(int) Load 67(gs_ub)
92: 8(int) AtomicUMin 66(gs_ua) 69 70 91
Store 72(out_u1) 92
93: 8(int) Load 67(gs_ub)
94: 2 AtomicOr 66(gs_ua) 69 70 93
95: 8(int) Load 67(gs_ub)
96: 8(int) AtomicOr 66(gs_ua) 69 70 95
Store 72(out_u1) 96
97: 8(int) Load 67(gs_ub)
98: 2 AtomicXor 66(gs_ua) 69 70 97
99: 8(int) Load 67(gs_ub)
100: 8(int) AtomicXor 66(gs_ua) 69 70 99
Store 72(out_u1) 100
ReturnValue 62
FunctionEnd
22(ComputeShaderFunction1(vf1;vf1;vf1;): 6(float) Function None 18
19(inF0): 7(ptr) FunctionParameter
20(inF1): 7(ptr) FunctionParameter
21(inF2): 7(ptr) FunctionParameter
23: Label
ReturnValue 99
ReturnValue 62
FunctionEnd
34(ComputeShaderFunction2(vf2;vf2;vf2;vu2;vu2;): 24(fvec2) Function None 28
29(inF0): 25(ptr) FunctionParameter
@ -942,47 +957,48 @@ local_size = (1, 1, 1)
32(inU0): 27(ptr) FunctionParameter
33(inU1): 27(ptr) FunctionParameter
35: Label
111(out_u2): 27(ptr) Variable Function
104: 24(fvec2) Load 29(inF0)
105: 61(bool) All 104
109: 26(ivec2) Load 108(gs_ub2)
110: 2 AtomicIAdd 107(gs_ua2) 67 68 109
112: 26(ivec2) Load 108(gs_ub2)
113: 26(ivec2) AtomicIAdd 107(gs_ua2) 67 68 112
Store 111(out_u2) 113
114: 26(ivec2) Load 108(gs_ub2)
115: 2 AtomicAnd 107(gs_ua2) 67 68 114
116: 26(ivec2) Load 108(gs_ub2)
117: 26(ivec2) AtomicAnd 107(gs_ua2) 67 68 116
Store 111(out_u2) 117
118: 26(ivec2) Load 108(gs_ub2)
120: 26(ivec2) Load 119(gs_uc2)
121: 26(ivec2) AtomicCompareExchange 107(gs_ua2) 67 68 68 120 118
Store 111(out_u2) 121
122: 26(ivec2) Load 108(gs_ub2)
123: 26(ivec2) AtomicExchange 107(gs_ua2) 67 68 122
Store 111(out_u2) 123
124: 26(ivec2) Load 108(gs_ub2)
125: 2 AtomicSMax 107(gs_ua2) 67 68 124
126: 26(ivec2) Load 108(gs_ub2)
127: 26(ivec2) AtomicUMax 107(gs_ua2) 67 68 126
Store 111(out_u2) 127
128: 26(ivec2) Load 108(gs_ub2)
129: 2 AtomicSMin 107(gs_ua2) 67 68 128
130: 26(ivec2) Load 108(gs_ub2)
131: 26(ivec2) AtomicUMin 107(gs_ua2) 67 68 130
Store 111(out_u2) 131
132: 26(ivec2) Load 108(gs_ub2)
133: 2 AtomicOr 107(gs_ua2) 67 68 132
134: 26(ivec2) Load 108(gs_ub2)
135: 26(ivec2) AtomicOr 107(gs_ua2) 67 68 134
Store 111(out_u2) 135
136: 26(ivec2) Load 108(gs_ub2)
137: 2 AtomicXor 107(gs_ua2) 67 68 136
138: 26(ivec2) Load 108(gs_ub2)
139: 26(ivec2) AtomicXor 107(gs_ua2) 67 68 138
Store 111(out_u2) 139
ReturnValue 142
115(out_u2): 27(ptr) Variable Function
105: 24(fvec2) Load 29(inF0)
108: 106(bvec2) FOrdNotEqual 105 107
109: 61(bool) All 108
113: 26(ivec2) Load 112(gs_ub2)
114: 2 AtomicIAdd 111(gs_ua2) 69 70 113
116: 26(ivec2) Load 112(gs_ub2)
117: 26(ivec2) AtomicIAdd 111(gs_ua2) 69 70 116
Store 115(out_u2) 117
118: 26(ivec2) Load 112(gs_ub2)
119: 2 AtomicAnd 111(gs_ua2) 69 70 118
120: 26(ivec2) Load 112(gs_ub2)
121: 26(ivec2) AtomicAnd 111(gs_ua2) 69 70 120
Store 115(out_u2) 121
122: 26(ivec2) Load 112(gs_ub2)
124: 26(ivec2) Load 123(gs_uc2)
125: 26(ivec2) AtomicCompareExchange 111(gs_ua2) 69 70 70 124 122
Store 115(out_u2) 125
126: 26(ivec2) Load 112(gs_ub2)
127: 26(ivec2) AtomicExchange 111(gs_ua2) 69 70 126
Store 115(out_u2) 127
128: 26(ivec2) Load 112(gs_ub2)
129: 2 AtomicSMax 111(gs_ua2) 69 70 128
130: 26(ivec2) Load 112(gs_ub2)
131: 26(ivec2) AtomicUMax 111(gs_ua2) 69 70 130
Store 115(out_u2) 131
132: 26(ivec2) Load 112(gs_ub2)
133: 2 AtomicSMin 111(gs_ua2) 69 70 132
134: 26(ivec2) Load 112(gs_ub2)
135: 26(ivec2) AtomicUMin 111(gs_ua2) 69 70 134
Store 115(out_u2) 135
136: 26(ivec2) Load 112(gs_ub2)
137: 2 AtomicOr 111(gs_ua2) 69 70 136
138: 26(ivec2) Load 112(gs_ub2)
139: 26(ivec2) AtomicOr 111(gs_ua2) 69 70 138
Store 115(out_u2) 139
140: 26(ivec2) Load 112(gs_ub2)
141: 2 AtomicXor 111(gs_ua2) 69 70 140
142: 26(ivec2) Load 112(gs_ub2)
143: 26(ivec2) AtomicXor 111(gs_ua2) 69 70 142
Store 115(out_u2) 143
ReturnValue 146
FunctionEnd
46(ComputeShaderFunction3(vf3;vf3;vf3;vu3;vu3;): 36(fvec3) Function None 40
41(inF0): 37(ptr) FunctionParameter
@ -991,47 +1007,48 @@ local_size = (1, 1, 1)
44(inU0): 39(ptr) FunctionParameter
45(inU1): 39(ptr) FunctionParameter
47: Label
152(out_u3): 39(ptr) Variable Function
145: 36(fvec3) Load 41(inF0)
146: 61(bool) All 145
150: 38(ivec3) Load 149(gs_ub3)
151: 2 AtomicIAdd 148(gs_ua3) 67 68 150
153: 38(ivec3) Load 149(gs_ub3)
154: 38(ivec3) AtomicIAdd 148(gs_ua3) 67 68 153
Store 152(out_u3) 154
155: 38(ivec3) Load 149(gs_ub3)
156: 2 AtomicAnd 148(gs_ua3) 67 68 155
157: 38(ivec3) Load 149(gs_ub3)
158: 38(ivec3) AtomicAnd 148(gs_ua3) 67 68 157
Store 152(out_u3) 158
159: 38(ivec3) Load 149(gs_ub3)
161: 38(ivec3) Load 160(gs_uc3)
162: 38(ivec3) AtomicCompareExchange 148(gs_ua3) 67 68 68 161 159
Store 152(out_u3) 162
163: 38(ivec3) Load 149(gs_ub3)
164: 38(ivec3) AtomicExchange 148(gs_ua3) 67 68 163
Store 152(out_u3) 164
165: 38(ivec3) Load 149(gs_ub3)
166: 2 AtomicSMax 148(gs_ua3) 67 68 165
167: 38(ivec3) Load 149(gs_ub3)
168: 38(ivec3) AtomicUMax 148(gs_ua3) 67 68 167
Store 152(out_u3) 168
169: 38(ivec3) Load 149(gs_ub3)
170: 2 AtomicSMin 148(gs_ua3) 67 68 169
171: 38(ivec3) Load 149(gs_ub3)
172: 38(ivec3) AtomicUMin 148(gs_ua3) 67 68 171
Store 152(out_u3) 172
173: 38(ivec3) Load 149(gs_ub3)
174: 2 AtomicOr 148(gs_ua3) 67 68 173
175: 38(ivec3) Load 149(gs_ub3)
176: 38(ivec3) AtomicOr 148(gs_ua3) 67 68 175
Store 152(out_u3) 176
177: 38(ivec3) Load 149(gs_ub3)
178: 2 AtomicXor 148(gs_ua3) 67 68 177
179: 38(ivec3) Load 149(gs_ub3)
180: 38(ivec3) AtomicXor 148(gs_ua3) 67 68 179
Store 152(out_u3) 180
ReturnValue 182
159(out_u3): 39(ptr) Variable Function
149: 36(fvec3) Load 41(inF0)
152: 150(bvec3) FOrdNotEqual 149 151
153: 61(bool) All 152
157: 38(ivec3) Load 156(gs_ub3)
158: 2 AtomicIAdd 155(gs_ua3) 69 70 157
160: 38(ivec3) Load 156(gs_ub3)
161: 38(ivec3) AtomicIAdd 155(gs_ua3) 69 70 160
Store 159(out_u3) 161
162: 38(ivec3) Load 156(gs_ub3)
163: 2 AtomicAnd 155(gs_ua3) 69 70 162
164: 38(ivec3) Load 156(gs_ub3)
165: 38(ivec3) AtomicAnd 155(gs_ua3) 69 70 164
Store 159(out_u3) 165
166: 38(ivec3) Load 156(gs_ub3)
168: 38(ivec3) Load 167(gs_uc3)
169: 38(ivec3) AtomicCompareExchange 155(gs_ua3) 69 70 70 168 166
Store 159(out_u3) 169
170: 38(ivec3) Load 156(gs_ub3)
171: 38(ivec3) AtomicExchange 155(gs_ua3) 69 70 170
Store 159(out_u3) 171
172: 38(ivec3) Load 156(gs_ub3)
173: 2 AtomicSMax 155(gs_ua3) 69 70 172
174: 38(ivec3) Load 156(gs_ub3)
175: 38(ivec3) AtomicUMax 155(gs_ua3) 69 70 174
Store 159(out_u3) 175
176: 38(ivec3) Load 156(gs_ub3)
177: 2 AtomicSMin 155(gs_ua3) 69 70 176
178: 38(ivec3) Load 156(gs_ub3)
179: 38(ivec3) AtomicUMin 155(gs_ua3) 69 70 178
Store 159(out_u3) 179
180: 38(ivec3) Load 156(gs_ub3)
181: 2 AtomicOr 155(gs_ua3) 69 70 180
182: 38(ivec3) Load 156(gs_ub3)
183: 38(ivec3) AtomicOr 155(gs_ua3) 69 70 182
Store 159(out_u3) 183
184: 38(ivec3) Load 156(gs_ub3)
185: 2 AtomicXor 155(gs_ua3) 69 70 184
186: 38(ivec3) Load 156(gs_ub3)
187: 38(ivec3) AtomicXor 155(gs_ua3) 69 70 186
Store 159(out_u3) 187
ReturnValue 189
FunctionEnd
58(@ComputeShaderFunction(vf4;vf4;vf4;vu4;vu4;): 48(fvec4) Function None 52
53(inF0): 49(ptr) FunctionParameter
@ -1040,45 +1057,46 @@ local_size = (1, 1, 1)
56(inU0): 51(ptr) FunctionParameter
57(inU1): 51(ptr) FunctionParameter
59: Label
192(out_u4): 51(ptr) Variable Function
185: 48(fvec4) Load 53(inF0)
186: 61(bool) All 185
190: 50(ivec4) Load 189(gs_ub4)
191: 2 AtomicIAdd 188(gs_ua4) 67 68 190
193: 50(ivec4) Load 189(gs_ub4)
194: 50(ivec4) AtomicIAdd 188(gs_ua4) 67 68 193
Store 192(out_u4) 194
195: 50(ivec4) Load 189(gs_ub4)
196: 2 AtomicAnd 188(gs_ua4) 67 68 195
197: 50(ivec4) Load 189(gs_ub4)
198: 50(ivec4) AtomicAnd 188(gs_ua4) 67 68 197
Store 192(out_u4) 198
199: 50(ivec4) Load 189(gs_ub4)
201: 50(ivec4) Load 200(gs_uc4)
202: 50(ivec4) AtomicCompareExchange 188(gs_ua4) 67 68 68 201 199
Store 192(out_u4) 202
203: 50(ivec4) Load 189(gs_ub4)
204: 50(ivec4) AtomicExchange 188(gs_ua4) 67 68 203
Store 192(out_u4) 204
205: 50(ivec4) Load 189(gs_ub4)
206: 2 AtomicSMax 188(gs_ua4) 67 68 205
207: 50(ivec4) Load 189(gs_ub4)
208: 50(ivec4) AtomicUMax 188(gs_ua4) 67 68 207
Store 192(out_u4) 208
209: 50(ivec4) Load 189(gs_ub4)
210: 2 AtomicSMin 188(gs_ua4) 67 68 209
211: 50(ivec4) Load 189(gs_ub4)
212: 50(ivec4) AtomicUMin 188(gs_ua4) 67 68 211
Store 192(out_u4) 212
213: 50(ivec4) Load 189(gs_ub4)
214: 2 AtomicOr 188(gs_ua4) 67 68 213
215: 50(ivec4) Load 189(gs_ub4)
216: 50(ivec4) AtomicOr 188(gs_ua4) 67 68 215
Store 192(out_u4) 216
217: 50(ivec4) Load 189(gs_ub4)
218: 2 AtomicXor 188(gs_ua4) 67 68 217
219: 50(ivec4) Load 189(gs_ub4)
220: 50(ivec4) AtomicXor 188(gs_ua4) 67 68 219
Store 192(out_u4) 220
ReturnValue 222
202(out_u4): 51(ptr) Variable Function
192: 48(fvec4) Load 53(inF0)
195: 193(bvec4) FOrdNotEqual 192 194
196: 61(bool) All 195
200: 50(ivec4) Load 199(gs_ub4)
201: 2 AtomicIAdd 198(gs_ua4) 69 70 200
203: 50(ivec4) Load 199(gs_ub4)
204: 50(ivec4) AtomicIAdd 198(gs_ua4) 69 70 203
Store 202(out_u4) 204
205: 50(ivec4) Load 199(gs_ub4)
206: 2 AtomicAnd 198(gs_ua4) 69 70 205
207: 50(ivec4) Load 199(gs_ub4)
208: 50(ivec4) AtomicAnd 198(gs_ua4) 69 70 207
Store 202(out_u4) 208
209: 50(ivec4) Load 199(gs_ub4)
211: 50(ivec4) Load 210(gs_uc4)
212: 50(ivec4) AtomicCompareExchange 198(gs_ua4) 69 70 70 211 209
Store 202(out_u4) 212
213: 50(ivec4) Load 199(gs_ub4)
214: 50(ivec4) AtomicExchange 198(gs_ua4) 69 70 213
Store 202(out_u4) 214
215: 50(ivec4) Load 199(gs_ub4)
216: 2 AtomicSMax 198(gs_ua4) 69 70 215
217: 50(ivec4) Load 199(gs_ub4)
218: 50(ivec4) AtomicUMax 198(gs_ua4) 69 70 217
Store 202(out_u4) 218
219: 50(ivec4) Load 199(gs_ub4)
220: 2 AtomicSMin 198(gs_ua4) 69 70 219
221: 50(ivec4) Load 199(gs_ub4)
222: 50(ivec4) AtomicUMin 198(gs_ua4) 69 70 221
Store 202(out_u4) 222
223: 50(ivec4) Load 199(gs_ub4)
224: 2 AtomicOr 198(gs_ua4) 69 70 223
225: 50(ivec4) Load 199(gs_ub4)
226: 50(ivec4) AtomicOr 198(gs_ua4) 69 70 225
Store 202(out_u4) 226
227: 50(ivec4) Load 199(gs_ub4)
228: 2 AtomicXor 198(gs_ua4) 69 70 227
229: 50(ivec4) Load 199(gs_ub4)
230: 50(ivec4) AtomicXor 198(gs_ua4) 69 70 229
Store 202(out_u4) 230
ReturnValue 232
FunctionEnd

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -399,7 +399,7 @@ gl_FragCoord origin is upper left
Branch 25
25: Label
36: 9(int) Load 13(c)
SelectionMerge 40 None
SelectionMerge 40 DontFlatten
Switch 36 39
case 1: 37
case 2: 38

View File

@ -0,0 +1,43 @@
spv.arbPostDepthCoverage.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 18
Capability Shader
Capability SampleRateShading
Capability SampleMaskPostDepthCoverage
Extension "SPV_KHR_post_depth_coverage"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 8 13
ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 EarlyFragmentTests
ExecutionMode 4 PostDepthCoverage
Source GLSL 450
SourceExtension "GL_ARB_post_depth_coverage"
SourceExtension "GL_EXT_post_depth_coverage"
Name 4 "main"
Name 8 "readSampleMaskIn"
Name 13 "gl_SampleMaskIn"
Decorate 8(readSampleMaskIn) Location 0
Decorate 13(gl_SampleMaskIn) Flat
Decorate 13(gl_SampleMaskIn) BuiltIn SampleMask
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Output 6(int)
8(readSampleMaskIn): 7(ptr) Variable Output
9: TypeInt 32 0
10: 9(int) Constant 1
11: TypeArray 6(int) 10
12: TypePointer Input 11
13(gl_SampleMaskIn): 12(ptr) Variable Input
14: 6(int) Constant 0
15: TypePointer Input 6(int)
4(main): 2 Function None 3
5: Label
16: 15(ptr) AccessChain 13(gl_SampleMaskIn) 14
17: 6(int) Load 16
Store 8(readSampleMaskIn) 17
Return
FunctionEnd

View File

@ -0,0 +1,7 @@
spv.arbPostDepthCoverage_Error.frag
ERROR: 0:7: 'early_fragment_tests' : can only apply to a standalone qualifier
ERROR: 0:7: 'post_depth_coverage' : can only apply to a standalone qualifier
ERROR: 2 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,23 @@
spv.extPostDepthCoverage.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 6
Capability Shader
Capability SampleMaskPostDepthCoverage
Extension "SPV_KHR_post_depth_coverage"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 EarlyFragmentTests
ExecutionMode 4 PostDepthCoverage
Source ESSL 310
SourceExtension "GL_EXT_post_depth_coverage"
Name 4 "main"
2: TypeVoid
3: TypeFunction 2
4(main): 2 Function None 3
5: Label
Return
FunctionEnd

View File

@ -0,0 +1,4 @@
spv.extPostDepthCoverage_Error.frag
ERROR: Linking fragment stage: post_depth_coverage requires early_fragment_tests
SPIR-V is not generated for failed compile or link

View File

@ -1,19 +1,19 @@
spv.texture.sampler.transform.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 19
// Id's are bound by 20
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 9 16
EntryPoint Fragment 4 "main" 9 17
ExecutionMode 4 OriginUpperLeft
Source GLSL 440
Name 4 "main"
Name 9 "color"
Name 12 "tex"
Name 16 "coord"
Decorate 12(tex) DescriptorSet 0
Name 13 "tex"
Name 17 "coord"
Decorate 13(tex) DescriptorSet 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@ -21,16 +21,17 @@ spv.texture.sampler.transform.frag
8: TypePointer Output 7(fvec4)
9(color): 8(ptr) Variable Output
10: TypeImage 6(float) 2D sampled format:Unknown
11: TypePointer UniformConstant 10
12(tex): 11(ptr) Variable UniformConstant
14: TypeVector 6(float) 2
15: TypePointer Input 14(fvec2)
16(coord): 15(ptr) Variable Input
11: TypeSampledImage 10
12: TypePointer UniformConstant 11
13(tex): 12(ptr) Variable UniformConstant
15: TypeVector 6(float) 2
16: TypePointer Input 15(fvec2)
17(coord): 16(ptr) Variable Input
4(main): 2 Function None 3
5: Label
13: 10 Load 12(tex)
17: 14(fvec2) Load 16(coord)
18: 7(fvec4) ImageSampleImplicitLod 13 17
Store 9(color) 18
14: 11 Load 13(tex)
18: 15(fvec2) Load 17(coord)
19: 7(fvec4) ImageSampleImplicitLod 14 18
Store 9(color) 19
Return
FunctionEnd

View File

@ -18,7 +18,7 @@ float4 PixelShaderFunction(float4 input, int c, int d) : COLOR0
break;
}
switch (c) {
[branch] switch (c) {
case 1:
++input;
break;

View File

@ -45,6 +45,11 @@ echo Comparing single thread to multithread for all tests in current directory..
$EXE -i -C *.vert *.geom *.frag *.tes* *.comp > singleThread.out
$EXE -i -C *.vert *.geom *.frag *.tes* *.comp -t > multiThread.out
diff singleThread.out multiThread.out || HASERROR=1
if [ $HASERROR -eq 0 ]
then
rm singleThread.out
rm multiThread.out
fi
#
# entry point renaming tests
@ -147,4 +152,6 @@ else
echo Tests Failed.
fi
rm -f comp.spv frag.spv geom.spv tesc.spv tese.spv vert.spv
exit $HASERROR

View File

@ -2,6 +2,8 @@
#extension GL_OVR_multiview : enable
layout(num_views = 2) in;
void main() {
gl_Position = vec4(gl_ViewID_OVR, 0, 0, 0);
}

View File

@ -0,0 +1,13 @@
#version 450
#extension GL_ARB_post_depth_coverage : enable
#extension GL_EXT_post_depth_coverage : enable //according to ARB_post_depth_coverage,
//if both enabled, this one should be ignored
precision highp int;
layout(post_depth_coverage) in;
layout (location = 0) out int readSampleMaskIn;
void main () {
readSampleMaskIn = gl_SampleMaskIn[0];
}

View File

@ -0,0 +1,12 @@
#version 310 es
#extension GL_ARB_post_depth_coverage : enable
precision highp float;
layout(post_depth_coverage, location = 0) in float a; // should fail since post_depth_coverage may only
// be declared on in only (not with variable declarations)
void main () {
}

View File

@ -0,0 +1,9 @@
#version 310 es
#extension GL_EXT_post_depth_coverage : enable
layout(post_depth_coverage) in;
layout(early_fragment_tests) in;
void main () {
}

View File

@ -0,0 +1,9 @@
#version 450
#extension GL_EXT_post_depth_coverage : enable
layout(post_depth_coverage) in; // should fail since for GL_EXT_post_depth_coverage
// explicit declaration of early_fragment_tests is required
void main () {
}

View File

@ -43,7 +43,7 @@ layout(push_constant) buffer pcb { // ERROR, not on a buffer
layout(push_constant) uniform float pcfloat; // ERROR 2X: not on a non-block, and non-opaque outside block
layout(push_constant) uniform; // ERROR, needs an object
layout(std430, push_constant) uniform pcb1 { int a; } pcb1inst;
layout(push_constant) uniform pcb2 {
int a;
}; // Okay now to have no instance name

View File

@ -79,7 +79,8 @@ set(HEADERS
# set(BISON_GLSLParser_OUTPUT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp)
add_library(glslang STATIC ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS})
set_property(TARGET glslang PROPERTY FOLDER glslang POSITION_INDEPENDENT_CODE ON)
set_property(TARGET glslang PROPERTY FOLDER glslang)
set_property(TARGET glslang PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(glslang OGLCompiler OSDependent)
if(ENABLE_HLSL)
target_link_libraries(glslang HLSL)
@ -93,10 +94,14 @@ if(WIN32)
source_group("MachineIndependent\\Preprocessor" REGULAR_EXPRESSION "MachineIndependent/preprocessor/*")
endif(WIN32)
install(TARGETS glslang
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS glslang
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_GLSLANG_INSTALL)
foreach(file ${HEADERS})
get_filename_component(dir ${file} DIRECTORY)
install(FILES ${file} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang/${dir})
endforeach()
if(ENABLE_GLSLANG_INSTALL)
foreach(file ${HEADERS})
get_filename_component(dir ${file} DIRECTORY)
install(FILES ${file} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang/${dir})
endforeach()
endif(ENABLE_GLSLANG_INSTALL)

View File

@ -968,8 +968,10 @@ struct TShaderQualifiers {
int localSize[3]; // compute shader
int localSizeSpecId[3]; // compute shader specialization id for gl_WorkGroupSize
bool earlyFragmentTests; // fragment input
bool postDepthCoverage; // fragment input
TLayoutDepth layoutDepth;
bool blendEquation; // true if any blend equation was specified
int numViews; // multiview extenstions
#ifdef NV_EXTENSIONS
bool layoutOverrideCoverage; // true if layout override_coverage set
@ -992,8 +994,10 @@ struct TShaderQualifiers {
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
earlyFragmentTests = false;
postDepthCoverage = false;
layoutDepth = EldNone;
blendEquation = false;
numViews = TQualifier::layoutNotSet;
#ifdef NV_EXTENSIONS
layoutOverrideCoverage = false;
#endif
@ -1029,10 +1033,14 @@ struct TShaderQualifiers {
}
if (src.earlyFragmentTests)
earlyFragmentTests = true;
if (src.postDepthCoverage)
postDepthCoverage = true;
if (src.layoutDepth)
layoutDepth = src.layoutDepth;
if (src.blendEquation)
blendEquation = src.blendEquation;
if (src.numViews != TQualifier::layoutNotSet)
numViews = src.numViews;
#ifdef NV_EXTENSIONS
if (src.layoutOverrideCoverage)
layoutOverrideCoverage = src.layoutOverrideCoverage;

View File

@ -861,6 +861,15 @@ protected:
TType type;
};
//
// Selection control hints
//
enum TSelectionControl {
ESelectionControlNone,
ESelectionControlFlatten,
ESelectionControlDontFlatten,
};
//
// Loop control hints
//
@ -945,7 +954,11 @@ public:
// per process threadPoolAllocator, then it causes increased memory usage per compile
// it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int i, const TString& n, const TType& t)
: TIntermTyped(t), id(i), constSubtree(nullptr)
: TIntermTyped(t), id(i),
#ifdef ENABLE_HLSL
flattenSubset(-1),
#endif
constSubtree(nullptr)
{ name = n; }
virtual int getId() const { return id; }
virtual const TString& getName() const { return name; }
@ -956,9 +969,16 @@ public:
const TConstUnionArray& getConstArray() const { return constArray; }
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
TIntermTyped* getConstSubtree() const { return constSubtree; }
#ifdef ENABLE_HLSL
void setFlattenSubset(int subset) { flattenSubset = subset; }
int getFlattenSubset() const { return flattenSubset; } // -1 means full object
#endif
protected:
int id; // the unique id of the symbol this node represents
#ifdef ENABLE_HLSL
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
#endif
TString name; // the name of the symbol this node represents
TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
TIntermTyped* constSubtree;
@ -1274,19 +1294,22 @@ protected:
class TIntermSelection : public TIntermTyped {
public:
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {}
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {}
virtual void traverse(TIntermTraverser*);
virtual TIntermTyped* getCondition() const { return condition; }
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
virtual TIntermSelection* getAsSelectionNode() { return this; }
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
void setSelectionControl(TSelectionControl c) { control = c; }
TSelectionControl getSelectionControl() const { return control; }
protected:
TIntermTyped* condition;
TIntermNode* trueBlock;
TIntermNode* falseBlock;
TSelectionControl control; // selection control hint
};
//
@ -1297,15 +1320,18 @@ protected:
//
class TIntermSwitch : public TIntermNode {
public:
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { }
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b), control(ESelectionControlNone) { }
virtual void traverse(TIntermTraverser*);
virtual TIntermNode* getCondition() const { return condition; }
virtual TIntermAggregate* getBody() const { return body; }
virtual TIntermSwitch* getAsSwitchNode() { return this; }
virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
void setSelectionControl(TSelectionControl c) { control = c; }
TSelectionControl getSelectionControl() const { return control; }
protected:
TIntermTyped* condition;
TIntermAggregate* body;
TSelectionControl control; // selection control hint
};
enum TVisit

View File

@ -1614,7 +1614,7 @@ TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
//
// Returns the selection node created.
//
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc, TSelectionControl control)
{
//
// Don't prune the false path for compile-time constants; it's needed
@ -1623,6 +1623,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair no
TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
node->setLoc(loc);
node->setSelectionControl(control);
return node;
}
@ -1665,12 +1666,12 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
//
// Returns the selection node created, or nullptr if one could not be.
//
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc, TSelectionControl control)
{
// If it's void, go to the if-then-else selection()
if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
TIntermNodePair pair = { trueBlock, falseBlock };
return addSelection(cond, pair, loc);
return addSelection(cond, pair, loc, control);
}
//
@ -3186,6 +3187,11 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
}
struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
void visitSymbol(TIntermSymbol* symbol) override {
if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
symbol->getWritableType().getSampler().combined = true;
}
}
bool visitAggregate(TVisit, TIntermAggregate* ag) override {
using namespace std;
TIntermSequence& seq = ag->getSequence();
@ -3199,17 +3205,11 @@ struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
});
seq.erase(newEnd, seq.end());
// replace constructors with sampler/textures
// update textures into sampled textures
for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
TIntermSymbol* symbol = node->getAsSymbolNode();
if (!symbol) {
TIntermAggregate *constructor = node->getAsAggregate();
if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
if (!constructor->getSequence().empty())
node = constructor->getSequence()[0];
}
} else if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
symbol->getWritableType().getSampler().combined = true;
TIntermAggregate *constructor = node->getAsAggregate();
if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
if (!constructor->getSequence().empty())
node = constructor->getSequence()[0];
}
});
return true;

View File

@ -4015,6 +4015,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.shaderQualifiers.earlyFragmentTests = true;
return;
}
if (id == "post_depth_coverage") {
requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
publicType.shaderQualifiers.earlyFragmentTests = true;
}
publicType.shaderQualifiers.postDepthCoverage = true;
return;
}
for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) {
if (id == TQualifier::getLayoutDepthString(depth)) {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier");
@ -4206,6 +4214,11 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
return;
}
if (id == "num_views") {
requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views");
publicType.shaderQualifiers.numViews = value;
return;
}
#if NV_EXTENSIONS
if (language == EShLangVertex ||
@ -4788,6 +4801,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
error(loc, message, "invocations", "");
if (shaderQualifiers.earlyFragmentTests)
error(loc, message, "early_fragment_tests", "");
if (shaderQualifiers.postDepthCoverage)
error(loc, message, "post_depth_coverage", "");
for (int i = 0; i < 3; ++i) {
if (shaderQualifiers.localSize[i] > 1)
error(loc, message, "local_size", "");
@ -4804,6 +4819,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
}
if (shaderQualifiers.blendEquation)
error(loc, message, "blend equation", "");
if (shaderQualifiers.numViews != TQualifier::layoutNotSet)
error(loc, message, "num_views", "");
}
// Correct and/or advance an object's offset layout qualifier.
@ -6282,6 +6299,12 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
else
error(loc, "can only apply to 'in'", "early_fragment_tests", "");
}
if (publicType.shaderQualifiers.postDepthCoverage) {
if (publicType.qualifier.storage == EvqVaryingIn)
intermediate.setPostDepthCoverage();
else
error(loc, "can only apply to 'in'", "post_coverage_coverage", "");
}
if (publicType.shaderQualifiers.blendEquation) {
if (publicType.qualifier.storage != EvqVaryingOut)
error(loc, "can only apply to 'out'", "blend equation", "");

View File

@ -181,9 +181,11 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_stencil_export] = EBhDisable;
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
extensionBehavior[E_GL_ARB_post_depth_coverage] = 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;
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@ -316,8 +318,10 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_sparse_texture_clamp 1\n"
"#define GL_ARB_shader_stencil_export 1\n"
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
"#define GL_ARB_post_depth_coverage 1\n"
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
"#define GL_EXT_shader_image_load_formatted 1\n"
"#define GL_EXT_post_depth_coverage 1\n"
#ifdef AMD_EXTENSIONS
"#define GL_AMD_shader_ballot 1\n"

View File

@ -135,6 +135,7 @@ const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil_export";
// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage";
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";
@ -142,6 +143,12 @@ const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_lo
// EXT extensions
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
// Arrays of extensions for the above viewportEXTs duplications
const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage };
const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]);
// OVR extensions
const char* const E_GL_OVR_multiview = "GL_OVR_multiview";

View File

@ -1085,6 +1085,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
infoSink.debug << "gl_FragCoord origin is upper left\n";
if (earlyFragmentTests)
infoSink.debug << "using early_fragment_tests\n";
if (postDepthCoverage)
infoSink.debug << "using post_depth_coverage\n";
if (depthLayout != EldNone)
infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
if (blendEquations != 0) {

View File

@ -436,7 +436,10 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
void endNotifications() override {}
void endNotifications(EShLanguage) override {}
void beginNotifications(EShLanguage) override {}
void beginResolve(EShLanguage) override {}
void endResolve(EShLanguage) override {}
protected:
static int getLayoutSet(const glslang::TType& type) {
@ -704,13 +707,16 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate);
TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate);
resolver->beginNotifications(stage);
std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify);
std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify);
std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify);
resolver->endNotifications();
resolver->endNotifications(stage);
resolver->beginResolve(stage);
std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve);
std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve);
std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve);
resolver->endResolve(stage);
if (!hadError) {
// sort by id again, so we can use lower bound to find entries

View File

@ -101,6 +101,9 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
if (! earlyFragmentTests)
earlyFragmentTests = unit.earlyFragmentTests;
if (!postDepthCoverage)
postDepthCoverage = unit.postDepthCoverage;
if (depthLayout == EldNone)
depthLayout = unit.depthLayout;
else if (depthLayout != unit.depthLayout)
@ -485,6 +488,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
break;
case EShLangFragment:
// for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in
// ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage
// requiring explicit early_fragment_tests
if (getPostDepthCoverage() && !getEarlyFragmentTests())
error(infoSink, "post_depth_coverage requires early_fragment_tests");
break;
case EShLangCompute:
break;

View File

@ -164,8 +164,8 @@ public:
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), depthLayout(EldNone), depthReplacing(false), blendEquations(0),
xfbMode(false), multiStream(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
blendEquations(0), xfbMode(false), multiStream(false),
#ifdef NV_EXTENSIONS
layoutOverrideCoverage(false),
geoPassthroughEXT(false),
@ -276,8 +276,8 @@ public:
TIntermAggregate* makeAggregate(const TSourceLoc&);
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
bool areAllChildConst(TIntermAggregate* aggrNode);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&, TSelectionControl = ESelectionControlNone);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&, TSelectionControl = ESelectionControlNone);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
@ -403,6 +403,8 @@ public:
bool getPixelCenterInteger() const { return pixelCenterInteger; }
void setEarlyFragmentTests() { earlyFragmentTests = true; }
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
void setPostDepthCoverage() { postDepthCoverage = true; }
bool getPostDepthCoverage() const { return postDepthCoverage; }
bool setDepth(TLayoutDepth d)
{
if (depthLayout != EldNone)
@ -513,6 +515,7 @@ protected:
int localSize[3];
int localSizeSpecId[3];
bool earlyFragmentTests;
bool postDepthCoverage;
TLayoutDepth depthLayout;
bool depthReplacing;
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift

View File

@ -1,5 +1,8 @@
add_library(OSDependent STATIC ossource.cpp ../osinclude.h)
set_property(TARGET OSDependent PROPERTY FOLDER glslang POSITION_INDEPENDENT_CODE ON)
set_property(TARGET OSDependent PROPERTY FOLDER glslang)
set_property(TARGET OSDependent PROPERTY POSITION_INDEPENDENT_CODE ON)
install(TARGETS OSDependent
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS OSDependent
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_GLSLANG_INSTALL)

View File

@ -1,7 +1,8 @@
set(SOURCES ossource.cpp ../osinclude.h)
add_library(OSDependent STATIC ${SOURCES})
set_property(TARGET OSDependent PROPERTY FOLDER glslang POSITION_INDEPENDENT_CODE ON)
set_property(TARGET OSDependent PROPERTY FOLDER glslang)
set_property(TARGET OSDependent PROPERTY POSITION_INDEPENDENT_CODE ON)
# MinGW GCC complains about function pointer casts to void*.
# Turn that off with -fpermissive.
@ -13,5 +14,7 @@ if(WIN32)
source_group("Source" FILES ${SOURCES})
endif(WIN32)
install(TARGETS OSDependent
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS OSDependent
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_GLSLANG_INSTALL)

View File

@ -362,10 +362,10 @@ public:
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
// For setting up the environment (initialized in the constructor):
void setEnvInput(EShSource lang, EShLanguage stage, EShClient client, int version)
void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
{
environment.input.languageFamily = lang;
environment.input.stage = stage;
environment.input.stage = envStage;
environment.input.dialect = client;
environment.input.dialectVersion = version;
}
@ -583,7 +583,13 @@ public:
// Notification of a in or out variable
virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
// Called by mapIO when it has finished the notify pass
virtual void endNotifications() = 0;
virtual void endNotifications(EShLanguage stage) = 0;
// Called by mapIO when it starts its notify pass for the given stage
virtual void beginNotifications(EShLanguage stage) = 0;
// Called by mipIO when it starts its resolve pass for the given stage
virtual void beginResolve(EShLanguage stage) = 0;
// Called by mapIO when it has finished the resolve pass
virtual void endResolve(EShLanguage stage) = 0;
};
// Make one TProgram per set of shaders that will get linked together. Add all

View File

@ -28,8 +28,10 @@ if(BUILD_TESTING)
add_executable(glslangtests ${TEST_SOURCES})
set_property(TARGET glslangtests PROPERTY FOLDER tests)
glslang_set_link_args(glslangtests)
install(TARGETS glslangtests
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS glslangtests
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif(ENABLE_GLSLANG_INSTALL)
set(GLSLANG_TEST_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../Test")
# Supply a default test root directory, so that manual testing

View File

@ -226,6 +226,8 @@ INSTANTIATE_TEST_CASE_P(
"spv.aggOps.frag",
"spv.always-discard.frag",
"spv.always-discard2.frag",
"spv.arbPostDepthCoverage.frag",
"spv.arbPostDepthCoverage_Error.frag",
"spv.bitCast.frag",
"spv.bool.vert",
"spv.boolInBlock.frag",
@ -242,6 +244,8 @@ INSTANTIATE_TEST_CASE_P(
"spv.drawParams.vert",
"spv.doWhileLoop.frag",
"spv.earlyReturnDiscard.frag",
"spv.extPostDepthCoverage.frag",
"spv.extPostDepthCoverage_Error.frag",
"spv.flowControl.frag",
"spv.forLoop.frag",
"spv.forwardFun.frag",

View File

@ -18,11 +18,14 @@ set(HEADERS
hlslParseables.h)
add_library(HLSL STATIC ${SOURCES} ${HEADERS})
set_property(TARGET HLSL PROPERTY FOLDER hlsl POSITION_INDEPENDENT_CODE ON)
set_property(TARGET HLSL PROPERTY FOLDER hlsl)
set_property(TARGET HLSL PROPERTY POSITION_INDEPENDENT_CODE ON)
if(WIN32)
source_group("Source" FILES ${SOURCES} ${HEADERS})
endif(WIN32)
install(TARGETS HLSL
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(ENABLE_GLSLANG_INSTALL)
install(TARGETS HLSL
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_GLSLANG_INSTALL)

View File

@ -2870,23 +2870,6 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
return false;
}
// This is to guarantee we do this no matter how we get out of the stack frame.
// This way there's no bug if an early return forgets to do it.
struct tFinalize {
tFinalize(HlslParseContext& p) : parseContext(p) { }
~tFinalize() { parseContext.finalizeFlattening(); }
HlslParseContext& parseContext;
private:
const tFinalize& operator=(const tFinalize&) { return *this; }
tFinalize(const tFinalize& f) : parseContext(f.parseContext) { }
} finalize(parseContext);
// Initialize the flattening accumulation data, so we can track data across multiple bracket or
// dot operators. This can also be nested, e.g, for [], so we have to track each nesting
// level: hence the init and finalize. Even though in practice these must be
// constants, they are parsed no matter what.
parseContext.initFlattening();
// Something was found, chain as many postfix operations as exist.
do {
TSourceLoc loc = token.loc;
@ -3218,10 +3201,10 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
return acceptScopedCompoundStatement(statement);
case EHTokIf:
return acceptSelectionStatement(statement);
return acceptSelectionStatement(statement, attributes);
case EHTokSwitch:
return acceptSwitchStatement(statement);
return acceptSwitchStatement(statement, attributes);
case EHTokFor:
case EHTokDo:
@ -3334,10 +3317,12 @@ void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
// : IF LEFT_PAREN expression RIGHT_PAREN statement
// : IF LEFT_PAREN expression RIGHT_PAREN statement ELSE statement
//
bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement, const TAttributeMap& attributes)
{
TSourceLoc loc = token.loc;
const TSelectionControl control = parseContext.handleSelectionControl(attributes);
// IF
if (! acceptTokenClass(EHTokIf))
return false;
@ -3375,7 +3360,7 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
}
// Put the pieces together
statement = intermediate.addSelection(condition, thenElse, loc);
statement = intermediate.addSelection(condition, thenElse, loc, control);
parseContext.popScope();
--parseContext.controlFlowNestingLevel;
@ -3385,10 +3370,13 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
// switch_statement
// : SWITCH LEFT_PAREN expression RIGHT_PAREN compound_statement
//
bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement)
bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement, const TAttributeMap& attributes)
{
// SWITCH
TSourceLoc loc = token.loc;
const TSelectionControl control = parseContext.handleSelectionControl(attributes);
if (! acceptTokenClass(EHTokSwitch))
return false;
@ -3408,7 +3396,7 @@ bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement)
--parseContext.controlFlowNestingLevel;
if (statementOkay)
statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr);
statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr, control);
parseContext.popSwitchSequence();
parseContext.popScope();

View File

@ -116,8 +116,8 @@ namespace glslang {
bool acceptStatement(TIntermNode*&);
bool acceptNestedStatement(TIntermNode*&);
void acceptAttributes(TAttributeMap&);
bool acceptSelectionStatement(TIntermNode*&);
bool acceptSwitchStatement(TIntermNode*&);
bool acceptSelectionStatement(TIntermNode*&, const TAttributeMap&);
bool acceptSwitchStatement(TIntermNode*&, const TAttributeMap&);
bool acceptIterationStatement(TIntermNode*&, const TAttributeMap&);
bool acceptJumpStatement(TIntermNode*&);
bool acceptCaseLabel(TIntermNode*&);

View File

@ -1348,11 +1348,11 @@ TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
const TType dereferencedType(base->getType(), member); // dereferenced type
const TIntermSymbol& symbolNode = *base->getAsSymbolNode();
TIntermTyped* flattened = flattenAccess(symbolNode.getId(), member, dereferencedType);
TIntermTyped* flattened = flattenAccess(symbolNode.getId(), member, dereferencedType, symbolNode.getFlattenSubset());
return flattened ? flattened : base;
}
TIntermTyped* HlslParseContext::flattenAccess(int uniqueId, int member, const TType& dereferencedType)
TIntermTyped* HlslParseContext::flattenAccess(int uniqueId, int member, const TType& dereferencedType, int subset)
{
const auto flattenData = flattenMap.find(uniqueId);
@ -1360,18 +1360,24 @@ TIntermTyped* HlslParseContext::flattenAccess(int uniqueId, int member, const TT
return nullptr;
// Calculate new cumulative offset from the packed tree
flattenOffset.back() = flattenData->second.offsets[flattenOffset.back() + member];
int newSubset = flattenData->second.offsets[subset >= 0 ? subset + member : member];
TIntermSymbol* subsetSymbol;
if (isFinalFlattening(dereferencedType)) {
// Finished flattening: create symbol for variable
member = flattenData->second.offsets[flattenOffset.back()];
member = flattenData->second.offsets[newSubset];
const TVariable* memberVariable = flattenData->second.members[member];
return intermediate.addSymbol(*memberVariable);
subsetSymbol = intermediate.addSymbol(*memberVariable);
subsetSymbol->setFlattenSubset(-1);
} else {
// If this is not the final flattening, accumulate the position and return
// an object of the partially dereferenced type.
return new TIntermSymbol(uniqueId, "flattenShadow", dereferencedType);
subsetSymbol = new TIntermSymbol(uniqueId, "flattenShadow", dereferencedType);
subsetSymbol->setFlattenSubset(newSubset);
}
return subsetSymbol;
}
// Find and return the split IO TVariable for id, or nullptr if none.
@ -1753,11 +1759,9 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
flatten(loc, *variable);
const TTypeList* structure = variable->getType().getStruct();
for (int mem = 0; mem < (int)structure->size(); ++mem) {
initFlattening();
paramNodes = intermediate.growAggregate(paramNodes,
flattenAccess(variable->getUniqueId(), mem, *(*structure)[mem].type),
loc);
finalizeFlattening();
}
} else {
// Add the parameter to the AST
@ -2482,7 +2486,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
TIntermTyped* noFlattenRHS = intermediate.addSymbol(*rhsTempVar, loc);
// Add this to the aggregate being built.
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, noFlattenRHS, right, loc), loc);
assignList = intermediate.growAggregate(assignList,
intermediate.addAssign(op, noFlattenRHS, right, loc), loc);
}
}
}
@ -2498,7 +2503,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
const TIntermTyped* outerLeft = left;
const TIntermTyped* outerRight = right;
const auto getMember = [&](bool isLeft, TIntermTyped* node, int member, TIntermTyped* splitNode, int splitMember) -> TIntermTyped * {
const auto getMember = [&](bool isLeft, TIntermTyped* node, int member, TIntermTyped* splitNode, int splitMember)
-> TIntermTyped * {
TIntermTyped* subTree;
const bool flattened = isLeft ? isFlattenLeft : isFlattenRight;
@ -2514,12 +2520,15 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
if (split && derefType.isBuiltInInterstageIO(language)) {
// copy from interstage IO builtin if needed
subTree = intermediate.addSymbol(*interstageBuiltInIo.find(HlslParseContext::tInterstageIoData(derefType, outer->getType()))->second);
subTree = intermediate.addSymbol(*interstageBuiltInIo.find(
HlslParseContext::tInterstageIoData(derefType, outer->getType()))->second);
// Arrayness of builtIn symbols isn't handled by the normal recursion: it's been extracted and moved to the builtin.
// Arrayness of builtIn symbols isn't handled by the normal recursion:
// it's been extracted and moved to the builtin.
if (subTree->getType().isArray() && !arrayElement.empty()) {
const TType splitDerefType(subTree->getType(), arrayElement.back());
subTree = intermediate.addIndex(EOpIndexDirect, subTree, intermediate.addConstantUnion(arrayElement.back(), loc), loc);
subTree = intermediate.addIndex(EOpIndexDirect, subTree,
intermediate.addConstantUnion(arrayElement.back(), loc), loc);
subTree->setType(splitDerefType);
}
} else if (flattened && isFinalFlattening(derefType)) {
@ -2540,8 +2549,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
// Use the proper RHS node: a new symbol from a TVariable, copy
// of an TIntermSymbol node, or sometimes the right node directly.
right = rhsTempVar ? intermediate.addSymbol(*rhsTempVar, loc) :
cloneSymNode ? intermediate.addSymbol(*cloneSymNode) :
right = rhsTempVar != nullptr ? intermediate.addSymbol(*rhsTempVar, loc) :
cloneSymNode != nullptr ? intermediate.addSymbol(*cloneSymNode) :
right;
// Cannot use auto here, because this is recursive, and auto can't work out the type without seeing the
@ -2566,8 +2575,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
TIntermTyped* subLeft = getMember(true, left, element, left, element);
TIntermTyped* subRight = getMember(false, right, element, right, element);
TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, element, splitLeft, element) : subLeft;
TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, element, splitRight, element) : subRight;
TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, element, splitLeft, element)
: subLeft;
TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, element, splitRight, element)
: subRight;
traverse(subLeft, subRight, subSplitLeft, subSplitRight);
@ -2595,8 +2606,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
TIntermTyped* subRight = getMember(false, right, member, right, member);
// If there is no splitting, use the same values to avoid inefficiency.
TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, member, splitLeft, memberL) : subLeft;
TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, member, splitRight, memberR) : subRight;
TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, member, splitLeft, memberL)
: subLeft;
TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, member, splitRight, memberR)
: subRight;
const TBuiltInVariable leftBuiltIn = subSplitLeft->getType().getQualifier().builtIn;
@ -2604,16 +2617,22 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
// Clip and cull distance builtin assignment is complex in its own right, and is handled in
// a separate function dedicated to that task. See comment above assignClipCullDistance;
assignList = intermediate.growAggregate(assignList, assignClipCullDistance(loc, op, subSplitLeft, subSplitRight), loc);
} else if ((!isFlattenLeft && !isFlattenRight &&
!typeL.containsBuiltInInterstageIO(language) && !typeR.containsBuiltInInterstageIO(language))) {
// If this is the final flattening (no nested types below to flatten) we'll copy the member, else
// recurse into the type hierarchy. However, if splitting the struct, that means we can copy a whole
// subtree here IFF it does not itself contain any interstage built-in IO variables, so we only have to
// recurse into it if there's something for splitting to do. That can save a lot of AST verbosity for
assignList = intermediate.growAggregate(assignList, assignClipCullDistance(loc, op, subSplitLeft,
subSplitRight), loc);
} else if (!isFlattenLeft && !isFlattenRight &&
!typeL.containsBuiltInInterstageIO(language) &&
!typeR.containsBuiltInInterstageIO(language)) {
// If this is the final flattening (no nested types below to flatten)
// we'll copy the member, else recurse into the type hierarchy.
// However, if splitting the struct, that means we can copy a whole
// subtree here IFF it does not itself contain any interstage built-in
// IO variables, so we only have to recurse into it if there's something
// for splitting to do. That can save a lot of AST verbosity for
// a bunch of memberwise copies.
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subSplitLeft, subSplitRight, loc), loc);
assignList = intermediate.growAggregate(assignList,
intermediate.addAssign(op, subSplitLeft, subSplitRight, loc),
loc);
} else {
traverse(subLeft, subRight, subSplitLeft, subSplitRight);
}
@ -4082,6 +4101,28 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
break;
}
case EOpAny: // fall through
case EOpAll:
{
TIntermTyped* typedArg = arguments->getAsTyped();
// HLSL allows float/etc types here, and the SPIR-V opcode requires a bool.
// We'll convert here. Note that for efficiency, we could add a smarter
// decomposition for some type cases, e.g, maybe by decomposing a dot product.
if (typedArg->getType().getBasicType() != EbtBool) {
const TType boolType(EbtBool, EvqTemporary,
typedArg->getVectorSize(),
typedArg->getMatrixCols(),
typedArg->getMatrixRows(),
typedArg->isVector());
typedArg = intermediate.addConversion(EOpConstructBool, boolType, typedArg);
node->getAsUnaryNode()->setOperand(typedArg);
}
break;
}
case EOpSaturate:
{
// saturate(a) -> clamp(a,0,1)
@ -4893,11 +4934,8 @@ void HlslParseContext::expandArguments(const TSourceLoc& loc, const TFunction& f
if (wasFlattened(arg) && shouldFlatten(*function[param].type)) {
// Need to pass the structure members instead of the structure.
TVector<TIntermTyped*> memberArgs;
for (int memb = 0; memb < (int)arg->getType().getStruct()->size(); ++memb) {
initFlattening();
for (int memb = 0; memb < (int)arg->getType().getStruct()->size(); ++memb)
memberArgs.push_back(flattenAccess(arg, memb));
finalizeFlattening();
}
setArgList(param + functionParamNumberOffset, memberArgs);
}
}
@ -8242,6 +8280,19 @@ bool HlslParseContext::handleOutputGeometry(const TSourceLoc& loc, const TLayout
return true;
}
//
// Selection hints
//
TSelectionControl HlslParseContext::handleSelectionControl(const TAttributeMap& attributes) const
{
if (attributes.contains(EatFlatten))
return ESelectionControlFlatten;
else if (attributes.contains(EatBranch))
return ESelectionControlDontFlatten;
else
return ESelectionControlNone;
}
//
// Loop hints
//
@ -8255,7 +8306,6 @@ TLoopControl HlslParseContext::handleLoopControl(const TAttributeMap& attributes
return ELoopControlNone;
}
//
// Updating default qualifier for the case of a declaration with just a qualifier,
// no type, block, or identifier.
@ -8394,7 +8444,7 @@ void HlslParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIn
// Turn the top-level node sequence built up of wrapupSwitchSubsequence
// into a switch node.
//
TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements, TSelectionControl control)
{
wrapupSwitchSubsequence(lastStatements, nullptr);
@ -8421,6 +8471,7 @@ TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* ex
TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
switchNode->setLoc(loc);
switchNode->setSelectionControl(control);
return switchNode;
}

View File

@ -159,7 +159,7 @@ public:
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body, TSelectionControl control);
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
@ -198,16 +198,15 @@ public:
bool handleOutputGeometry(const TSourceLoc&, const TLayoutGeometry& geometry);
bool handleInputGeometry(const TSourceLoc&, const TLayoutGeometry& geometry);
// Determine selection control from attributes
TSelectionControl handleSelectionControl(const TAttributeMap& attributes) const;
// Determine loop control from attributes
TLoopControl handleLoopControl(const TAttributeMap& attributes) const;
// Potentially rename shader entry point function
void renameShaderFunction(const TString*& name) const;
// Reset data for incrementally built referencing of flattened composite structures
void initFlattening() { flattenLevel.push_back(0); flattenOffset.push_back(0); }
void finalizeFlattening() { flattenLevel.pop_back(); flattenOffset.pop_back(); }
// Share struct buffer deep types
void shareStructBufferType(TType&);
@ -242,7 +241,7 @@ protected:
// Array and struct flattening
TIntermTyped* flattenAccess(TIntermTyped* base, int member);
TIntermTyped* flattenAccess(int uniqueId, int member, const TType&);
TIntermTyped* flattenAccess(int uniqueId, int member, const TType&, int subset = -1);
bool shouldFlatten(const TType&) const;
bool wasFlattened(const TIntermTyped* node) const;
bool wasFlattened(int id) const { return flattenMap.find(id) != flattenMap.end(); }
@ -368,7 +367,6 @@ protected:
TMap<int, TFlattenData> flattenMap;
TVector<int> flattenLevel; // nested postfix operator level for flattening
TVector<int> flattenOffset; // cumulative offset for flattening
// IO-type map. Maps a pure symbol-table form of a structure-member list into
// each of the (up to) three kinds of IO, as each as different allowed decorations,