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";
+static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
#endif // #ifndef GLSLextKHR_H
if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
+
+ switch (glslangIntermediate->getInterlockOrdering()) {
+ case glslang::EioPixelInterlockOrdered: mode = spv::ExecutionModePixelInterlockOrderedEXT; break;
+ case glslang::EioPixelInterlockUnordered: mode = spv::ExecutionModePixelInterlockUnorderedEXT; break;
+ case glslang::EioSampleInterlockOrdered: mode = spv::ExecutionModeSampleInterlockOrderedEXT; break;
+ case glslang::EioSampleInterlockUnordered: mode = spv::ExecutionModeSampleInterlockUnorderedEXT; break;
+ case glslang::EioShadingRateInterlockOrdered: mode = spv::ExecutionModeShadingRateInterlockOrderedEXT; break;
+ case glslang::EioShadingRateInterlockUnordered: mode = spv::ExecutionModeShadingRateInterlockUnorderedEXT; break;
+ default: mode = spv::ExecutionModeMax; break;
+ }
+ if (mode != spv::ExecutionModeMax) {
+ builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
+ if (mode == spv::ExecutionModeShadingRateInterlockOrderedEXT ||
+ mode == spv::ExecutionModeShadingRateInterlockUnorderedEXT) {
+ builder.addCapability(spv::CapabilityFragmentShaderShadingRateInterlockEXT);
+ } else if (mode == spv::ExecutionModePixelInterlockOrderedEXT ||
+ mode == spv::ExecutionModePixelInterlockUnorderedEXT) {
+ builder.addCapability(spv::CapabilityFragmentShaderPixelInterlockEXT);
+ } else {
+ builder.addCapability(spv::CapabilityFragmentShaderSampleInterlockEXT);
+ }
+ builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
+ }
+
break;
case EShLangCompute:
case glslang::EOpCooperativeMatrixStore:
noReturnValue = true;
break;
+ case glslang::EOpBeginInvocationInterlock:
+ case glslang::EOpEndInvocationInterlock:
+ builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
+ noReturnValue = true;
+ break;
default:
break;
builder.createNoResultOp(spv::OpTerminateRayNV);
return 0;
#endif
+
+ case glslang::EOpBeginInvocationInterlock:
+ builder.createNoResultOp(spv::OpBeginInvocationInterlockEXT);
+ return 0;
+ case glslang::EOpEndInvocationInterlock:
+ builder.createNoResultOp(spv::OpEndInvocationInterlockEXT);
+ return 0;
+
default:
logger->missingFunctionality("unknown operation with no arguments");
return 0;
case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV";
#endif
+ case ExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT";
+ case ExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT";
+ case ExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT";
+ case ExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT";
+ case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT";
+ case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
+
case ExecutionModeCeiling:
default: return "Bad";
}
case CapabilityCooperativeMatrixNV: return "CooperativeMatrixNV";
+ case CapabilityFragmentShaderSampleInterlockEXT: return "CapabilityFragmentShaderSampleInterlockEXT";
+ case CapabilityFragmentShaderPixelInterlockEXT: return "CapabilityFragmentShaderPixelInterlockEXT";
+ case CapabilityFragmentShaderShadingRateInterlockEXT: return "CapabilityFragmentShaderShadingRateInterlockEXT";
+
default: return "Bad";
}
}
case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV";
case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV";
+ case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT";
+ case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT";
+
default:
return "Bad";
}
InstructionDesc[OpModuleProcessed].setResultAndType(false, false);
InstructionDesc[OpTypeCooperativeMatrixNV].setResultAndType(true, false);
InstructionDesc[OpCooperativeMatrixStoreNV].setResultAndType(false, false);
+ InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false);
+ InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false);
// Specific additional context-dependent operands
ExecutionModeDerivativeGroupQuadsNV = 5289,
ExecutionModeDerivativeGroupLinearNV = 5290,
ExecutionModeOutputTrianglesNV = 5298,
+ ExecutionModePixelInterlockOrderedEXT = 5366,
+ ExecutionModePixelInterlockUnorderedEXT = 5367,
+ ExecutionModeSampleInterlockOrderedEXT = 5368,
+ ExecutionModeSampleInterlockUnorderedEXT = 5369,
+ ExecutionModeShadingRateInterlockOrderedEXT = 5370,
+ ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
ExecutionModeMax = 0x7fffffff,
};
BuiltInHitTNV = 5332,
BuiltInHitKindNV = 5333,
BuiltInIncomingRayFlagsNV = 5351,
+ BuiltInWarpsPerSMNV = 5374,
+ BuiltInSMCountNV = 5375,
+ BuiltInWarpIDNV = 5376,
+ BuiltInSMIDNV = 5377,
BuiltInMax = 0x7fffffff,
};
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
CapabilityComputeDerivativeGroupLinearNV = 5350,
CapabilityCooperativeMatrixNV = 5357,
+ CapabilityFragmentShaderSampleInterlockEXT = 5363,
+ CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
+ CapabilityShaderSMBuiltinsNV = 5373,
+ CapabilityFragmentShaderPixelInterlockEXT = 5378,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
+ CapabilityIntegerFunctions2INTEL = 5584,
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
OpCooperativeMatrixStoreNV = 5360,
OpCooperativeMatrixMulAddNV = 5361,
OpCooperativeMatrixLengthNV = 5362,
+ OpBeginInvocationInterlockEXT = 5364,
+ OpEndInvocationInterlockEXT = 5365,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
OpSubgroupImageBlockWriteINTEL = 5578,
OpSubgroupImageMediaBlockReadINTEL = 5580,
OpSubgroupImageMediaBlockWriteINTEL = 5581,
+ OpUCountLeadingZerosINTEL = 5585,
+ OpUCountTrailingZerosINTEL = 5586,
+ OpAbsISubINTEL = 5587,
+ OpAbsUSubINTEL = 5588,
+ OpIAddSatINTEL = 5589,
+ OpUAddSatINTEL = 5590,
+ OpIAverageINTEL = 5591,
+ OpUAverageINTEL = 5592,
+ OpIAverageRoundedINTEL = 5593,
+ OpUAverageRoundedINTEL = 5594,
+ OpISubSatINTEL = 5595,
+ OpUSubSatINTEL = 5596,
+ OpIMul32x16INTEL = 5597,
+ OpUMul32x16INTEL = 5598,
OpDecorateString = 5632,
OpDecorateStringGOOGLE = 5632,
OpMemberDecorateString = 5633,
case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+ case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
+ case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
case OpDecorateString: *hasResult = false; *hasResultType = false; break;
- case OpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
- case OpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break;
case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
+ case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */
--- /dev/null
+spv.fsi.frag
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 24
+
+ Capability Shader
+ Capability CapabilityFragmentShaderSampleInterlockEXT
+ Extension "SPV_EXT_fragment_shader_interlock"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main"
+ ExecutionMode 4 OriginUpperLeft
+ ExecutionMode 4 SampleInterlockOrderedEXT
+ Source GLSL 450
+ SourceExtension "GL_ARB_fragment_shader_interlock"
+ Name 4 "main"
+ Name 7 "B1"
+ MemberName 7(B1) 0 "x"
+ Name 9 "b1"
+ Name 17 "im"
+ MemberDecorate 7(B1) 0 Coherent
+ MemberDecorate 7(B1) 0 Offset 0
+ Decorate 7(B1) BufferBlock
+ Decorate 9(b1) DescriptorSet 0
+ Decorate 9(b1) Binding 0
+ Decorate 17(im) DescriptorSet 0
+ Decorate 17(im) Binding 1
+ Decorate 17(im) Coherent
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7(B1): TypeStruct 6(int)
+ 8: TypePointer Uniform 7(B1)
+ 9(b1): 8(ptr) Variable Uniform
+ 10: 6(int) Constant 0
+ 11: 6(int) Constant 1
+ 12: TypePointer Uniform 6(int)
+ 14: TypeFloat 32
+ 15: TypeImage 14(float) 2D nonsampled format:Rgba32f
+ 16: TypePointer UniformConstant 15
+ 17(im): 16(ptr) Variable UniformConstant
+ 19: TypeVector 6(int) 2
+ 20: 19(ivec2) ConstantComposite 10 10
+ 21: TypeVector 14(float) 4
+ 22: 14(float) Constant 0
+ 23: 21(fvec4) ConstantComposite 22 22 22 22
+ 4(main): 2 Function None 3
+ 5: Label
+ BeginInvocationInterlockEXT
+ 13: 12(ptr) AccessChain 9(b1) 10
+ Store 13 11
+ 18: 15 Load 17(im)
+ ImageWrite 18 20 23
+ EndInvocationInterlockEXT
+ Return
+ FunctionEnd
--- /dev/null
+spv.fsi_Error.frag
+ERROR: 0:4: 'pixel_interlock_ordered' : can only apply to 'in'
+ERROR: 0:7: 'pixel_interlock_unordered' : cannot change previously set fragment shader interlock ordering
+ERROR: 0:11: '' : beginInvocationInterlockARB() must be in main()
+ERROR: 0:12: '' : endInvocationInterlockARB() must be in main()
+ERROR: 0:17: '' : endInvocationInterlockARB() must only be called once
+ERROR: 0:18: '' : beginInvocationInterlockARB() must only be called once
+ERROR: 0:18: '' : beginInvocationInterlockARB() must be called before endInvocationInterlockARB()
+ERROR: 0:22: '' : endInvocationInterlockARB() cannot be placed after a return from main()
+ERROR: 0:22: '' : endInvocationInterlockARB() must only be called once
+ERROR: 9 compilation errors. No code generated.
+
+
+SPIR-V is not generated for failed compile or link
--- /dev/null
+#version 450\r
+#extension GL_ARB_fragment_shader_interlock : enable\r
+\r
+layout(set = 0, binding = 0) coherent buffer B1 {\r
+ layout(offset = 0) int x;\r
+} b1;\r
+\r
+layout(set = 0, binding = 1, rgba32f) coherent uniform image2D im;\r
+\r
+layout(sample_interlock_ordered) in;\r
+\r
+void main() {\r
+\r
+ beginInvocationInterlockARB();\r
+\r
+ b1.x = 1;\r
+ imageStore(im, ivec2(0,0), vec4(0));\r
+\r
+ endInvocationInterlockARB();\r
+}\r
--- /dev/null
+#version 450\r
+#extension GL_ARB_fragment_shader_interlock : enable\r
+\r
+layout(pixel_interlock_ordered) out;\r
+\r
+layout(pixel_interlock_ordered) in;\r
+layout(pixel_interlock_unordered) in;\r
+\r
+void foo()\r
+{\r
+ beginInvocationInterlockARB();\r
+ endInvocationInterlockARB();\r
+}\r
+\r
+void main() {\r
+\r
+ endInvocationInterlockARB();\r
+ beginInvocationInterlockARB();\r
+\r
+ return;\r
+\r
+ endInvocationInterlockARB();\r
+}\r
EBlendCount
};
+enum TInterlockOrdering {
+ EioNone,
+ EioPixelInterlockOrdered,
+ EioPixelInterlockUnordered,
+ EioSampleInterlockOrdered,
+ EioSampleInterlockUnordered,
+ EioShadingRateInterlockOrdered,
+ EioShadingRateInterlockUnordered,
+
+ EioCount,
+};
+
class TQualifier {
public:
static const int layoutNotSet = -1;
default: return 0;
}
}
+ static const char* getInterlockOrderingString(TInterlockOrdering order)
+ {
+ switch (order) {
+ case EioPixelInterlockOrdered: return "pixel_interlock_ordered";
+ case EioPixelInterlockUnordered: return "pixel_interlock_unordered";
+ case EioSampleInterlockOrdered: return "sample_interlock_ordered";
+ case EioSampleInterlockUnordered: return "sample_interlock_unordered";
+ case EioShadingRateInterlockOrdered: return "shading_rate_interlock_ordered";
+ case EioShadingRateInterlockUnordered: return "shading_rate_interlock_unordered";
+ default: return "none";
+ }
+ }
};
// Qualifiers that don't need to be keep per object. They have shader scope, not object scope.
TLayoutDepth layoutDepth;
bool blendEquation; // true if any blend equation was specified
int numViews; // multiview extenstions
+ TInterlockOrdering interlockOrdering;
#ifdef NV_EXTENSIONS
bool layoutOverrideCoverage; // true if layout override_coverage set
layoutDerivativeGroupLinear = false;
primitives = TQualifier::layoutNotSet;
#endif
+ interlockOrdering = EioNone;
}
// Merge in characteristics from the 'src' qualifier. They can override when
if (src.primitives != TQualifier::layoutNotSet)
primitives = src.primitives;
#endif
+
+ if (src.interlockOrdering != EioNone)
+ interlockOrdering = src.interlockOrdering;
}
};
EOpCooperativeMatrixStore,
EOpCooperativeMatrixMulAdd,
+ EOpBeginInvocationInterlock, // Fragment only
+ EOpEndInvocationInterlock, // Fragment only
+
//
// Branch
//
"\n");
}
+ stageBuiltins[EShLangFragment].append(
+ "void beginInvocationInterlockARB(void);"
+ "void endInvocationInterlockARB(void);");
+
#ifdef AMD_EXTENSIONS
// GL_AMD_shader_explicit_vertex_parameter
if (profile != EEsProfile && version >= 450) {
if (profile != EEsProfile)
symbolTable.relateToOperator("interpolateAtVertexAMD", EOpInterpolateAtVertex);
#endif
+
+ symbolTable.relateToOperator("beginInvocationInterlockARB", EOpBeginInvocationInterlock);
+ symbolTable.relateToOperator("endInvocationInterlockARB", EOpEndInvocationInterlock);
+
break;
case EShLangCompute:
error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
}
break;
+ case EOpBeginInvocationInterlock:
+ if (language != EShLangFragment)
+ error(loc, "beginInvocationInterlockARB() must be in a fragment shader", "", "");
+ if (! inMain)
+ error(loc, "beginInvocationInterlockARB() must be in main()", "", "");
+ else if (postEntryPointReturn)
+ error(loc, "beginInvocationInterlockARB() cannot be placed after a return from main()", "", "");
+ if (controlFlowNestingLevel > 0)
+ error(loc, "beginInvocationInterlockARB() cannot be placed within flow control", "", "");
+
+ if (beginInvocationInterlockCount > 0)
+ error(loc, "beginInvocationInterlockARB() must only be called once", "", "");
+ if (endInvocationInterlockCount > 0)
+ error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
+
+ beginInvocationInterlockCount++;
+
+ // default to pixel_interlock_ordered
+ if (intermediate.getInterlockOrdering() == EioNone)
+ intermediate.setInterlockOrdering(EioPixelInterlockOrdered);
+ break;
+ case EOpEndInvocationInterlock:
+ if (language != EShLangFragment)
+ error(loc, "endInvocationInterlockARB() must be in a fragment shader", "", "");
+ if (! inMain)
+ error(loc, "endInvocationInterlockARB() must be in main()", "", "");
+ else if (postEntryPointReturn)
+ error(loc, "endInvocationInterlockARB() cannot be placed after a return from main()", "", "");
+ if (controlFlowNestingLevel > 0)
+ error(loc, "endInvocationInterlockARB() cannot be placed within flow control", "", "");
+
+ if (endInvocationInterlockCount > 0)
+ error(loc, "endInvocationInterlockARB() must only be called once", "", "");
+ if (beginInvocationInterlockCount == 0)
+ error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
+
+ endInvocationInterlockCount++;
+ break;
default:
break;
}
return;
}
}
+ for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) {
+ if (id == TQualifier::getInterlockOrderingString(order)) {
+ requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier");
+ profileRequires(loc, ECoreProfile | ECompatibilityProfile, 450, nullptr, "fragment shader interlock layout qualifier");
+ requireExtensions(loc, 1, &E_GL_ARB_fragment_shader_interlock, TQualifier::getInterlockOrderingString(order));
+ if (order == EioShadingRateInterlockOrdered || order == EioShadingRateInterlockUnordered)
+ requireExtensions(loc, 1, &E_GL_NV_shading_rate_image, TQualifier::getInterlockOrderingString(order));
+ publicType.shaderQualifiers.interlockOrdering = order;
+ return;
+ }
+ }
if (id.compare(0, 13, "blend_support") == 0) {
bool found = false;
for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
error(loc, message, "blend equation", "");
if (shaderQualifiers.numViews != TQualifier::layoutNotSet)
error(loc, message, "num_views", "");
+ if (shaderQualifiers.interlockOrdering != EioNone)
+ error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
}
// Correct and/or advance an object's offset layout qualifier.
if (publicType.qualifier.storage != EvqVaryingOut)
error(loc, "can only apply to 'out'", "blend equation", "");
}
+ if (publicType.shaderQualifiers.interlockOrdering) {
+ if (publicType.qualifier.storage == EvqVaryingIn) {
+ if (!intermediate.setInterlockOrdering(publicType.shaderQualifiers.interlockOrdering))
+ error(loc, "cannot change previously set fragment shader interlock ordering", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
+ }
+ else
+ error(loc, "can only apply to 'in'", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
+ }
#ifdef NV_EXTENSIONS
if (publicType.shaderQualifiers.layoutDerivativeGroupQuads &&
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
postEntryPointReturn(false),
contextPragma(true, false),
+ beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
limits(resources.limits),
globalUniformBlock(nullptr),
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
TList<int> switchLevel;
struct TPragma contextPragma;
+ int beginInvocationInterlockCount;
+ int endInvocationInterlockCount;
protected:
TParseContextBase(TParseContextBase&);
// 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_ARB_shader_viewport_layer_array] = EBhDisable;
+ extensionBehavior[E_GL_ARB_fragment_shader_interlock] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
"#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_ARB_fragment_shader_interlock 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"
// 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_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array";
+const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock";
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
}
infoSink.debug << "\n";
}
+ if (interlockOrdering != EioNone)
+ infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n";
break;
#ifdef NV_EXTENSIONS
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false),
- vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
+ vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
hlslFunctionality1(false),
blendEquations(0), xfbMode(false), multiStream(false),
void setPointMode() { pointMode = true; }
bool getPointMode() const { return pointMode; }
+ bool setInterlockOrdering(TInterlockOrdering o)
+ {
+ if (interlockOrdering != EioNone)
+ return interlockOrdering == o;
+ interlockOrdering = o;
+ return true;
+ }
+ TInterlockOrdering getInterlockOrdering() const { return interlockOrdering; }
+
bool setLocalSize(int dim, int size)
{
if (localSize[dim] > 1)
bool originUpperLeft;
TVertexSpacing vertexSpacing;
TVertexOrder vertexOrder;
+ TInterlockOrdering interlockOrdering;
bool pointMode;
int localSize[3];
int localSizeSpecId[3];
"spv.fragmentDensity.vert",
"spv.fragmentDensity-es.frag",
"spv.fragmentDensity-neg.frag",
+ "spv.fsi.frag",
+ "spv.fsi_Error.frag",
"spv.fullyCovered.frag",
"spv.functionCall.frag",
"spv.functionNestedOpaque.vert",
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Tools",
"subdir" : "External/spirv-tools",
- "commit" : "9dfd4b8358077bdbe8e2f9388572b5376c370f5d"
+ "commit" : "2c0111e6eba779cf30e8c7f5a733ea0762895ba0"
},
{
"name" : "spirv-tools/external/spirv-headers",
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Headers",
"subdir" : "External/spirv-tools/external/spirv-headers",
- "commit" : "4b0985f29277a81f5ce88feb0502cc44d6d5e7c3"
+ "commit" : "8b911bd2ba37677037b38c9bd286c7c05701bcda"
}
]
}