Support extension EXT_shader_quad_control
This commit is contained in:
parent
f6f9840eab
commit
725017a588
15 changed files with 232 additions and 3 deletions
|
|
@ -53,6 +53,7 @@ static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_termi
|
||||||
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
|
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
|
||||||
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
|
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
|
||||||
static const char* const E_SPV_KHR_fragment_shader_barycentric = "SPV_KHR_fragment_shader_barycentric";
|
static const char* const E_SPV_KHR_fragment_shader_barycentric = "SPV_KHR_fragment_shader_barycentric";
|
||||||
|
static const char* const E_SPV_KHR_quad_control = "SPV_KHR_quad_control";
|
||||||
static const char* const E_SPV_AMD_shader_early_and_late_fragment_tests = "SPV_AMD_shader_early_and_late_fragment_tests";
|
static const char* const E_SPV_AMD_shader_early_and_late_fragment_tests = "SPV_AMD_shader_early_and_late_fragment_tests";
|
||||||
static const char* const E_SPV_KHR_ray_tracing_position_fetch = "SPV_KHR_ray_tracing_position_fetch";
|
static const char* const E_SPV_KHR_ray_tracing_position_fetch = "SPV_KHR_ray_tracing_position_fetch";
|
||||||
static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_cooperative_matrix";
|
static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_cooperative_matrix";
|
||||||
|
|
|
||||||
|
|
@ -1640,6 +1640,20 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
||||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeMaximallyReconvergesKHR);
|
builder.addExecutionMode(shaderEntry, spv::ExecutionModeMaximallyReconvergesKHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (glslangIntermediate->getQuadDerivMode())
|
||||||
|
{
|
||||||
|
builder.addCapability(spv::CapabilityQuadControlKHR);
|
||||||
|
builder.addExtension(spv::E_SPV_KHR_quad_control);
|
||||||
|
builder.addExecutionMode(shaderEntry, spv::ExecutionModeQuadDerivativesKHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glslangIntermediate->getReqFullQuadsMode())
|
||||||
|
{
|
||||||
|
builder.addCapability(spv::CapabilityQuadControlKHR);
|
||||||
|
builder.addExtension(spv::E_SPV_KHR_quad_control);
|
||||||
|
builder.addExecutionMode(shaderEntry, spv::ExecutionModeRequireFullQuadsKHR);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
switch (glslangIntermediate->getStage()) {
|
switch (glslangIntermediate->getStage()) {
|
||||||
case EShLangVertex:
|
case EShLangVertex:
|
||||||
|
|
@ -7173,7 +7187,9 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
|
||||||
case glslang::EOpSubgroupExclusiveXor:
|
case glslang::EOpSubgroupExclusiveXor:
|
||||||
case glslang::EOpSubgroupQuadSwapHorizontal:
|
case glslang::EOpSubgroupQuadSwapHorizontal:
|
||||||
case glslang::EOpSubgroupQuadSwapVertical:
|
case glslang::EOpSubgroupQuadSwapVertical:
|
||||||
case glslang::EOpSubgroupQuadSwapDiagonal: {
|
case glslang::EOpSubgroupQuadSwapDiagonal:
|
||||||
|
case glslang::EOpSubgroupQuadAll:
|
||||||
|
case glslang::EOpSubgroupQuadAny: {
|
||||||
std::vector<spv::Id> operands;
|
std::vector<spv::Id> operands;
|
||||||
operands.push_back(operand);
|
operands.push_back(operand);
|
||||||
return createSubgroupOperation(op, typeId, operands, typeProxy);
|
return createSubgroupOperation(op, typeId, operands, typeProxy);
|
||||||
|
|
@ -8278,6 +8294,11 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
|
||||||
case glslang::EOpSubgroupElect:
|
case glslang::EOpSubgroupElect:
|
||||||
builder.addCapability(spv::CapabilityGroupNonUniform);
|
builder.addCapability(spv::CapabilityGroupNonUniform);
|
||||||
break;
|
break;
|
||||||
|
case glslang::EOpSubgroupQuadAll:
|
||||||
|
case glslang::EOpSubgroupQuadAny:
|
||||||
|
builder.addExtension(spv::E_SPV_KHR_quad_control);
|
||||||
|
builder.addCapability(spv::CapabilityQuadControlKHR);
|
||||||
|
// pass through
|
||||||
case glslang::EOpSubgroupAll:
|
case glslang::EOpSubgroupAll:
|
||||||
case glslang::EOpSubgroupAny:
|
case glslang::EOpSubgroupAny:
|
||||||
case glslang::EOpSubgroupAllEqual:
|
case glslang::EOpSubgroupAllEqual:
|
||||||
|
|
@ -8385,7 +8406,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
|
||||||
// Figure out which opcode to use.
|
// Figure out which opcode to use.
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case glslang::EOpSubgroupElect: opCode = spv::OpGroupNonUniformElect; break;
|
case glslang::EOpSubgroupElect: opCode = spv::OpGroupNonUniformElect; break;
|
||||||
|
case glslang::EOpSubgroupQuadAll: opCode = spv::OpGroupNonUniformQuadAllKHR; break;
|
||||||
case glslang::EOpSubgroupAll: opCode = spv::OpGroupNonUniformAll; break;
|
case glslang::EOpSubgroupAll: opCode = spv::OpGroupNonUniformAll; break;
|
||||||
|
case glslang::EOpSubgroupQuadAny: opCode = spv::OpGroupNonUniformQuadAnyKHR; break;
|
||||||
case glslang::EOpSubgroupAny: opCode = spv::OpGroupNonUniformAny; break;
|
case glslang::EOpSubgroupAny: opCode = spv::OpGroupNonUniformAny; break;
|
||||||
case glslang::EOpSubgroupAllEqual: opCode = spv::OpGroupNonUniformAllEqual; break;
|
case glslang::EOpSubgroupAllEqual: opCode = spv::OpGroupNonUniformAllEqual; break;
|
||||||
case glslang::EOpSubgroupBroadcast: opCode = spv::OpGroupNonUniformBroadcast; break;
|
case glslang::EOpSubgroupBroadcast: opCode = spv::OpGroupNonUniformBroadcast; break;
|
||||||
|
|
@ -8582,7 +8605,10 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
|
||||||
|
|
||||||
// Every operation begins with the Execution Scope operand.
|
// Every operation begins with the Execution Scope operand.
|
||||||
spv::IdImmediate executionScope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
|
spv::IdImmediate executionScope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
|
||||||
|
// All other ops need the execution scope. Quad Control Ops don't need scope, it's always Quad.
|
||||||
|
if (opCode != spv::OpGroupNonUniformQuadAllKHR && opCode != spv::OpGroupNonUniformQuadAnyKHR) {
|
||||||
spvGroupOperands.push_back(executionScope);
|
spvGroupOperands.push_back(executionScope);
|
||||||
|
}
|
||||||
|
|
||||||
// Next, for all operations that use a Group Operation, push that as an operand.
|
// Next, for all operations that use a Group Operation, push that as an operand.
|
||||||
if (groupOperation != spv::GroupOperationMax) {
|
if (groupOperation != spv::GroupOperationMax) {
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,9 @@ const char* ExecutionModeString(int mode)
|
||||||
case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL";
|
case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL";
|
||||||
case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL";
|
case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL";
|
||||||
|
|
||||||
|
case ExecutionModeRequireFullQuadsKHR: return "RequireFullQuadsKHR";
|
||||||
|
case ExecutionModeQuadDerivativesKHR: return "QuadDerivativesKHR";
|
||||||
|
|
||||||
case ExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT";
|
case ExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT";
|
||||||
case ExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT";
|
case ExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT";
|
||||||
case ExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT";
|
case ExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT";
|
||||||
|
|
@ -1033,6 +1036,7 @@ const char* CapabilityString(int info)
|
||||||
|
|
||||||
case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT";
|
case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT";
|
||||||
case CapabilityShaderClockKHR: return "ShaderClockKHR";
|
case CapabilityShaderClockKHR: return "ShaderClockKHR";
|
||||||
|
case CapabilityQuadControlKHR: return "QuadControlKHR";
|
||||||
case CapabilityInt64ImageEXT: return "Int64ImageEXT";
|
case CapabilityInt64ImageEXT: return "Int64ImageEXT";
|
||||||
|
|
||||||
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
|
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
|
||||||
|
|
@ -1433,6 +1437,9 @@ const char* OpcodeString(int op)
|
||||||
case 4430: return "OpSubgroupAllEqualKHR";
|
case 4430: return "OpSubgroupAllEqualKHR";
|
||||||
case 4432: return "OpSubgroupReadInvocationKHR";
|
case 4432: return "OpSubgroupReadInvocationKHR";
|
||||||
|
|
||||||
|
case OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR";
|
||||||
|
case OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR";
|
||||||
|
|
||||||
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
|
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
|
||||||
case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
|
case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
|
||||||
case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
|
case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
|
||||||
|
|
@ -2940,6 +2947,8 @@ void Parameterize()
|
||||||
|
|
||||||
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
|
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
|
||||||
|
|
||||||
|
InstructionDesc[OpGroupNonUniformQuadAllKHR].operands.push(OperandId, "'Predicate'");
|
||||||
|
InstructionDesc[OpGroupNonUniformQuadAnyKHR].operands.push(OperandId, "'Predicate'");
|
||||||
InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
|
InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
|
||||||
|
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'");
|
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'");
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,8 @@ enum ExecutionMode {
|
||||||
ExecutionModeStencilRefUnchangedBackAMD = 5082,
|
ExecutionModeStencilRefUnchangedBackAMD = 5082,
|
||||||
ExecutionModeStencilRefGreaterBackAMD = 5083,
|
ExecutionModeStencilRefGreaterBackAMD = 5083,
|
||||||
ExecutionModeStencilRefLessBackAMD = 5084,
|
ExecutionModeStencilRefLessBackAMD = 5084,
|
||||||
|
ExecutionModeQuadDerivativesKHR = 5088,
|
||||||
|
ExecutionModeRequireFullQuadsKHR = 5089,
|
||||||
ExecutionModeOutputLinesEXT = 5269,
|
ExecutionModeOutputLinesEXT = 5269,
|
||||||
ExecutionModeOutputLinesNV = 5269,
|
ExecutionModeOutputLinesNV = 5269,
|
||||||
ExecutionModeOutputPrimitivesEXT = 5270,
|
ExecutionModeOutputPrimitivesEXT = 5270,
|
||||||
|
|
@ -1040,6 +1042,7 @@ enum Capability {
|
||||||
CapabilityImageReadWriteLodAMD = 5015,
|
CapabilityImageReadWriteLodAMD = 5015,
|
||||||
CapabilityInt64ImageEXT = 5016,
|
CapabilityInt64ImageEXT = 5016,
|
||||||
CapabilityShaderClockKHR = 5055,
|
CapabilityShaderClockKHR = 5055,
|
||||||
|
CapabilityQuadControlKHR = 5087,
|
||||||
CapabilitySampleMaskOverrideCoverageNV = 5249,
|
CapabilitySampleMaskOverrideCoverageNV = 5249,
|
||||||
CapabilityGeometryShaderPassthroughNV = 5251,
|
CapabilityGeometryShaderPassthroughNV = 5251,
|
||||||
CapabilityShaderViewportIndexLayerEXT = 5254,
|
CapabilityShaderViewportIndexLayerEXT = 5254,
|
||||||
|
|
@ -1705,6 +1708,8 @@ enum Op {
|
||||||
OpFragmentMaskFetchAMD = 5011,
|
OpFragmentMaskFetchAMD = 5011,
|
||||||
OpFragmentFetchAMD = 5012,
|
OpFragmentFetchAMD = 5012,
|
||||||
OpReadClockKHR = 5056,
|
OpReadClockKHR = 5056,
|
||||||
|
OpGroupNonUniformQuadAllKHR = 5110,
|
||||||
|
OpGroupNonUniformQuadAnyKHR = 5111,
|
||||||
OpHitObjectRecordHitMotionNV = 5249,
|
OpHitObjectRecordHitMotionNV = 5249,
|
||||||
OpHitObjectRecordHitWithIndexMotionNV = 5250,
|
OpHitObjectRecordHitWithIndexMotionNV = 5250,
|
||||||
OpHitObjectRecordMissMotionNV = 5251,
|
OpHitObjectRecordMissMotionNV = 5251,
|
||||||
|
|
@ -2375,6 +2380,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
||||||
case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break;
|
case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break;
|
case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break;
|
case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpCopyLogical: *hasResult = true; *hasResultType = true; break;
|
case OpCopyLogical: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpPtrEqual: *hasResult = true; *hasResultType = true; break;
|
case OpPtrEqual: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
|
case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
|
||||||
|
|
|
||||||
76
Test/baseResults/spv.1.6.quad.frag.out
Normal file
76
Test/baseResults/spv.1.6.quad.frag.out
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
spv.1.6.quad.frag
|
||||||
|
// Module Version 10600
|
||||||
|
// Generated by (magic number): 8000b
|
||||||
|
// Id's are bound by 39
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
Capability GroupNonUniform
|
||||||
|
Capability GroupNonUniformVote
|
||||||
|
Capability QuadControlKHR
|
||||||
|
Extension "SPV_KHR_quad_control"
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "main" 16 33
|
||||||
|
ExecutionMode 4 QuadDerivativesKHR
|
||||||
|
ExecutionMode 4 RequireFullQuadsKHR
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source GLSL 460
|
||||||
|
SourceExtension "GL_EXT_shader_quad_control"
|
||||||
|
SourceExtension "GL_KHR_shader_subgroup_basic"
|
||||||
|
SourceExtension "GL_KHR_shader_subgroup_vote"
|
||||||
|
Name 4 "main"
|
||||||
|
Name 8 "bTemp"
|
||||||
|
Name 16 "iInput"
|
||||||
|
Name 33 "bOut"
|
||||||
|
Decorate 16(iInput) Flat
|
||||||
|
Decorate 16(iInput) Location 0
|
||||||
|
Decorate 33(bOut) Location 0
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeBool
|
||||||
|
7: TypePointer Function 6(bool)
|
||||||
|
9: 6(bool) ConstantFalse
|
||||||
|
14: TypeInt 32 1
|
||||||
|
15: TypePointer Input 14(int)
|
||||||
|
16(iInput): 15(ptr) Variable Input
|
||||||
|
18: 14(int) Constant 0
|
||||||
|
20: TypeInt 32 0
|
||||||
|
21: 20(int) Constant 3
|
||||||
|
32: TypePointer Output 14(int)
|
||||||
|
33(bOut): 32(ptr) Variable Output
|
||||||
|
35: 6(bool) ConstantTrue
|
||||||
|
37: 14(int) Constant 1
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
8(bTemp): 7(ptr) Variable Function
|
||||||
|
Store 8(bTemp) 9
|
||||||
|
10: 6(bool) Load 8(bTemp)
|
||||||
|
11: 6(bool) LogicalNot 10
|
||||||
|
SelectionMerge 13 None
|
||||||
|
BranchConditional 11 12 13
|
||||||
|
12: Label
|
||||||
|
17: 14(int) Load 16(iInput)
|
||||||
|
19: 6(bool) SGreaterThan 17 18
|
||||||
|
22: 6(bool) GroupNonUniformQuadAllKHR 19
|
||||||
|
Branch 13
|
||||||
|
13: Label
|
||||||
|
23: 6(bool) Phi 10 5 22 12
|
||||||
|
Store 8(bTemp) 23
|
||||||
|
24: 6(bool) Load 8(bTemp)
|
||||||
|
25: 6(bool) LogicalNot 24
|
||||||
|
SelectionMerge 27 None
|
||||||
|
BranchConditional 25 26 27
|
||||||
|
26: Label
|
||||||
|
28: 14(int) Load 16(iInput)
|
||||||
|
29: 6(bool) SGreaterThan 28 18
|
||||||
|
30: 6(bool) GroupNonUniformQuadAnyKHR 29
|
||||||
|
Branch 27
|
||||||
|
27: Label
|
||||||
|
31: 6(bool) Phi 24 13 30 26
|
||||||
|
Store 8(bTemp) 31
|
||||||
|
34: 6(bool) Load 8(bTemp)
|
||||||
|
36: 6(bool) LogicalEqual 34 35
|
||||||
|
38: 14(int) Select 36 37 18
|
||||||
|
Store 33(bOut) 38
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
||||||
21
Test/spv.1.6.quad.frag
Normal file
21
Test/spv.1.6.quad.frag
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#version 460 core
|
||||||
|
#extension GL_KHR_shader_subgroup_basic: require
|
||||||
|
#extension GL_EXT_shader_quad_control: require
|
||||||
|
#extension GL_KHR_shader_subgroup_vote: require
|
||||||
|
|
||||||
|
layout (full_quads) in;
|
||||||
|
layout (quad_derivatives) in;
|
||||||
|
|
||||||
|
flat in int iInput;
|
||||||
|
|
||||||
|
out int bOut;
|
||||||
|
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
bool bTemp = false;
|
||||||
|
|
||||||
|
// EXT_shader_quad_control required begin
|
||||||
|
bTemp = bTemp || subgroupQuadAll(iInput > 0); // GL_KHR_shader_subgroup_vote
|
||||||
|
bTemp = bTemp || subgroupQuadAny(iInput > 0); // GL_KHR_shader_subgroup_vote
|
||||||
|
bOut = bTemp == true ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
@ -852,6 +852,8 @@ public:
|
||||||
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
||||||
layoutSecondaryViewportRelativeOffset = -2048;
|
layoutSecondaryViewportRelativeOffset = -2048;
|
||||||
layoutShaderRecord = false;
|
layoutShaderRecord = false;
|
||||||
|
layoutFullQuads = false;
|
||||||
|
layoutQuadDeriv = false;
|
||||||
layoutHitObjectShaderRecordNV = false;
|
layoutHitObjectShaderRecordNV = false;
|
||||||
layoutBindlessSampler = false;
|
layoutBindlessSampler = false;
|
||||||
layoutBindlessImage = false;
|
layoutBindlessImage = false;
|
||||||
|
|
@ -948,6 +950,8 @@ public:
|
||||||
bool layoutViewportRelative;
|
bool layoutViewportRelative;
|
||||||
int layoutSecondaryViewportRelativeOffset;
|
int layoutSecondaryViewportRelativeOffset;
|
||||||
bool layoutShaderRecord;
|
bool layoutShaderRecord;
|
||||||
|
bool layoutFullQuads;
|
||||||
|
bool layoutQuadDeriv;
|
||||||
bool layoutHitObjectShaderRecordNV;
|
bool layoutHitObjectShaderRecordNV;
|
||||||
|
|
||||||
// GL_EXT_spirv_intrinsics
|
// GL_EXT_spirv_intrinsics
|
||||||
|
|
@ -1055,6 +1059,8 @@ public:
|
||||||
TLayoutFormat getFormat() const { return layoutFormat; }
|
TLayoutFormat getFormat() const { return layoutFormat; }
|
||||||
bool isPushConstant() const { return layoutPushConstant; }
|
bool isPushConstant() const { return layoutPushConstant; }
|
||||||
bool isShaderRecord() const { return layoutShaderRecord; }
|
bool isShaderRecord() const { return layoutShaderRecord; }
|
||||||
|
bool isFullQuads() const { return layoutFullQuads; }
|
||||||
|
bool isQuadDeriv() const { return layoutQuadDeriv; }
|
||||||
bool hasHitObjectShaderRecordNV() const { return layoutHitObjectShaderRecordNV; }
|
bool hasHitObjectShaderRecordNV() const { return layoutHitObjectShaderRecordNV; }
|
||||||
bool hasBufferReference() const { return layoutBufferReference; }
|
bool hasBufferReference() const { return layoutBufferReference; }
|
||||||
bool hasBufferReferenceAlign() const
|
bool hasBufferReferenceAlign() const
|
||||||
|
|
@ -2206,6 +2212,10 @@ public:
|
||||||
|
|
||||||
if (qualifier.layoutShaderRecord)
|
if (qualifier.layoutShaderRecord)
|
||||||
appendStr(" shaderRecordNV");
|
appendStr(" shaderRecordNV");
|
||||||
|
if (qualifier.layoutFullQuads)
|
||||||
|
appendStr(" full_quads");
|
||||||
|
if (qualifier.layoutQuadDeriv)
|
||||||
|
appendStr(" quad_derivatives");
|
||||||
if (qualifier.layoutHitObjectShaderRecordNV)
|
if (qualifier.layoutHitObjectShaderRecordNV)
|
||||||
appendStr(" hitobjectshaderrecordnv");
|
appendStr(" hitobjectshaderrecordnv");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -538,6 +538,8 @@ enum TOperator {
|
||||||
EOpSubgroupQuadSwapHorizontal,
|
EOpSubgroupQuadSwapHorizontal,
|
||||||
EOpSubgroupQuadSwapVertical,
|
EOpSubgroupQuadSwapVertical,
|
||||||
EOpSubgroupQuadSwapDiagonal,
|
EOpSubgroupQuadSwapDiagonal,
|
||||||
|
EOpSubgroupQuadAll,
|
||||||
|
EOpSubgroupQuadAny,
|
||||||
|
|
||||||
EOpSubgroupPartition,
|
EOpSubgroupPartition,
|
||||||
EOpSubgroupPartitionedAdd,
|
EOpSubgroupPartitionedAdd,
|
||||||
|
|
|
||||||
|
|
@ -2227,6 +2227,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GL_EXT_shader_quad_control
|
||||||
|
if ((profile == EEsProfile && version >= 310) ||
|
||||||
|
(profile != EEsProfile && version >= 140)) {
|
||||||
|
commonBuiltins.append(
|
||||||
|
"bool subgroupQuadAll(bool);\n"
|
||||||
|
"bool subgroupQuadAny(bool);\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (profile != EEsProfile && version >= 460) {
|
if (profile != EEsProfile && version >= 460) {
|
||||||
commonBuiltins.append(
|
commonBuiltins.append(
|
||||||
"bool anyInvocation(bool);"
|
"bool anyInvocation(bool);"
|
||||||
|
|
@ -8779,6 +8788,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||||
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
|
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GL_EXT_shader_quad_control
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
symbolTable.setFunctionExtensions("subgroupQuadAll", 1, &E_GL_KHR_shader_subgroup_vote);
|
||||||
|
symbolTable.setFunctionExtensions("subgroupQuadAny", 1, &E_GL_KHR_shader_subgroup_vote);
|
||||||
|
}
|
||||||
|
|
||||||
// GL_EXT_shader_tile_image
|
// GL_EXT_shader_tile_image
|
||||||
symbolTable.setFunctionExtensions("stencilAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
|
symbolTable.setFunctionExtensions("stencilAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
|
||||||
symbolTable.setFunctionExtensions("depthAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
|
symbolTable.setFunctionExtensions("depthAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
|
||||||
|
|
@ -9977,6 +9993,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||||
symbolTable.relateToOperator("shadow2DProjEXT", EOpTextureProj);
|
symbolTable.relateToOperator("shadow2DProjEXT", EOpTextureProj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GL_EXT_shader_quad_control
|
||||||
|
if ((profile == EEsProfile && version >= 310) ||
|
||||||
|
(profile != EEsProfile && version >= 140)) {
|
||||||
|
symbolTable.relateToOperator("subgroupQuadAll", EOpSubgroupQuadAll);
|
||||||
|
symbolTable.relateToOperator("subgroupQuadAny", EOpSubgroupQuadAny);
|
||||||
|
}
|
||||||
|
|
||||||
if ((profile == EEsProfile && version >= 310) ||
|
if ((profile == EEsProfile && version >= 310) ||
|
||||||
(profile != EEsProfile && version >= 140)) {
|
(profile != EEsProfile && version >= 140)) {
|
||||||
symbolTable.relateToOperator("textureWeightedQCOM", EOpImageSampleWeightedQCOM);
|
symbolTable.relateToOperator("textureWeightedQCOM", EOpImageSampleWeightedQCOM);
|
||||||
|
|
|
||||||
|
|
@ -1351,6 +1351,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
||||||
// - a user function.
|
// - a user function.
|
||||||
|
|
||||||
// Error check for a function requiring specific extensions present.
|
// Error check for a function requiring specific extensions present.
|
||||||
|
if (builtIn &&
|
||||||
|
(fnCandidate->getBuiltInOp() == EOpSubgroupQuadAll || fnCandidate->getBuiltInOp() == EOpSubgroupQuadAny))
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_shader_quad_control, fnCandidate->getName().c_str());
|
||||||
|
|
||||||
if (builtIn && fnCandidate->getNumExtensions())
|
if (builtIn && fnCandidate->getNumExtensions())
|
||||||
requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
|
requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
|
||||||
|
|
||||||
|
|
@ -3986,6 +3990,18 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
|
||||||
// Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
|
// Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
|
||||||
if (!isMemberCheck || structNestingLevel > 0)
|
if (!isMemberCheck || structNestingLevel > 0)
|
||||||
invariantCheck(loc, qualifier);
|
invariantCheck(loc, qualifier);
|
||||||
|
|
||||||
|
if (qualifier.isFullQuads()) {
|
||||||
|
if (qualifier.storage != EvqVaryingIn)
|
||||||
|
error(loc, "can only apply to input layout", "full_quads ", "");
|
||||||
|
intermediate.setReqFullQuadsMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qualifier.isQuadDeriv()) {
|
||||||
|
if (qualifier.storage != EvqVaryingIn)
|
||||||
|
error(loc, "can only apply to input layout", "quad_derivatives", "");
|
||||||
|
intermediate.setQuadDerivMode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -5859,6 +5875,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||||
publicType.shaderQualifiers.layoutOverrideCoverage = true;
|
publicType.shaderQualifiers.layoutOverrideCoverage = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (id == "full_quads")
|
||||||
|
{
|
||||||
|
const char* feature = "full_quads qualifier";
|
||||||
|
requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, feature);
|
||||||
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 140, E_GL_EXT_shader_quad_control, feature);
|
||||||
|
profileRequires(loc, EEsProfile, 310, E_GL_EXT_shader_quad_control, feature);
|
||||||
|
publicType.qualifier.layoutFullQuads = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (language == EShLangVertex ||
|
if (language == EShLangVertex ||
|
||||||
language == EShLangTessControl ||
|
language == EShLangTessControl ||
|
||||||
|
|
@ -5908,6 +5933,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id == "quad_derivatives")
|
||||||
|
{
|
||||||
|
const char* feature = "quad_derivatives qualifier";
|
||||||
|
requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, feature);
|
||||||
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 140, E_GL_EXT_shader_quad_control, feature);
|
||||||
|
profileRequires(loc, EEsProfile, 310, E_GL_EXT_shader_quad_control, feature);
|
||||||
|
publicType.qualifier.layoutQuadDeriv = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
|
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6336,6 +6371,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
||||||
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
|
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
|
||||||
if (src.layoutShaderRecord)
|
if (src.layoutShaderRecord)
|
||||||
dst.layoutShaderRecord = true;
|
dst.layoutShaderRecord = true;
|
||||||
|
if (src.layoutFullQuads)
|
||||||
|
dst.layoutFullQuads = true;
|
||||||
|
if (src.layoutQuadDeriv)
|
||||||
|
dst.layoutQuadDeriv = true;
|
||||||
if (src.layoutBindlessSampler)
|
if (src.layoutBindlessSampler)
|
||||||
dst.layoutBindlessSampler = true;
|
dst.layoutBindlessSampler = true;
|
||||||
if (src.layoutBindlessImage)
|
if (src.layoutBindlessImage)
|
||||||
|
|
|
||||||
|
|
@ -357,6 +357,7 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable;
|
extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_mesh_shader] = EBhDisable;
|
extensionBehavior[E_GL_EXT_mesh_shader] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_opacity_micromap] = EBhDisable;
|
extensionBehavior[E_GL_EXT_opacity_micromap] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_quad_control] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_ray_tracing_position_fetch] = EBhDisable;
|
extensionBehavior[E_GL_EXT_ray_tracing_position_fetch] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_tile_image] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_tile_image] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable;
|
extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable;
|
||||||
|
|
@ -584,6 +585,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_EXT_shader_atomic_float2 1\n"
|
"#define GL_EXT_shader_atomic_float2 1\n"
|
||||||
|
|
||||||
"#define GL_EXT_fragment_shader_barycentric 1\n"
|
"#define GL_EXT_fragment_shader_barycentric 1\n"
|
||||||
|
"#define GL_EXT_shader_quad_control 1\n"
|
||||||
"#define GL_EXT_texture_array 1\n"
|
"#define GL_EXT_texture_array 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,7 @@ const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intr
|
||||||
const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric";
|
const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric";
|
||||||
const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader";
|
const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader";
|
||||||
const char* const E_GL_EXT_opacity_micromap = "GL_EXT_opacity_micromap";
|
const char* const E_GL_EXT_opacity_micromap = "GL_EXT_opacity_micromap";
|
||||||
|
const char* const E_GL_EXT_shader_quad_control = "GL_EXT_shader_quad_control";
|
||||||
const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_instanced";
|
const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_instanced";
|
||||||
const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array";
|
const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array";
|
||||||
const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence";
|
const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence";
|
||||||
|
|
|
||||||
|
|
@ -597,6 +597,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
|
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
|
||||||
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
||||||
|
case EOpSubgroupQuadAll: out.debug << "subgroupQuadAll"; break;
|
||||||
|
case EOpSubgroupQuadAny: out.debug << "subgroupQuadAny"; break;
|
||||||
|
|
||||||
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
||||||
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
||||||
|
|
@ -1032,6 +1034,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
|
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
|
||||||
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
||||||
|
case EOpSubgroupQuadAll: out.debug << "subgroupQuadAll"; break;
|
||||||
|
case EOpSubgroupQuadAny: out.debug << "subgroupQuadAny"; break;
|
||||||
|
|
||||||
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
||||||
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,8 @@ public:
|
||||||
usePhysicalStorageBuffer(false),
|
usePhysicalStorageBuffer(false),
|
||||||
spirvRequirement(nullptr),
|
spirvRequirement(nullptr),
|
||||||
spirvExecutionMode(nullptr),
|
spirvExecutionMode(nullptr),
|
||||||
uniformLocationBase(0)
|
uniformLocationBase(0),
|
||||||
|
quadDerivMode(false), reqFullQuadsMode(false)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
|
|
@ -858,6 +859,10 @@ public:
|
||||||
|
|
||||||
void setXfbMode() { xfbMode = true; }
|
void setXfbMode() { xfbMode = true; }
|
||||||
bool getXfbMode() const { return xfbMode; }
|
bool getXfbMode() const { return xfbMode; }
|
||||||
|
void setQuadDerivMode(bool mode = true) { quadDerivMode = mode; }
|
||||||
|
bool getQuadDerivMode() const { return quadDerivMode; }
|
||||||
|
void setReqFullQuadsMode(bool mode = true) { reqFullQuadsMode = mode; }
|
||||||
|
bool getReqFullQuadsMode() const { return reqFullQuadsMode; }
|
||||||
void setMultiStream() { multiStream = true; }
|
void setMultiStream() { multiStream = true; }
|
||||||
bool isMultiStream() const { return multiStream; }
|
bool isMultiStream() const { return multiStream; }
|
||||||
bool setOutputPrimitive(TLayoutGeometry p)
|
bool setOutputPrimitive(TLayoutGeometry p)
|
||||||
|
|
@ -1197,6 +1202,8 @@ protected:
|
||||||
bool hlslFunctionality1;
|
bool hlslFunctionality1;
|
||||||
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
||||||
bool xfbMode;
|
bool xfbMode;
|
||||||
|
bool quadDerivMode;
|
||||||
|
bool reqFullQuadsMode;
|
||||||
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
||||||
bool multiStream;
|
bool multiStream;
|
||||||
bool layoutOverrideCoverage;
|
bool layoutOverrideCoverage;
|
||||||
|
|
|
||||||
|
|
@ -735,6 +735,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"spv.1.6.specConstant.comp",
|
"spv.1.6.specConstant.comp",
|
||||||
"spv.1.6.samplerBuffer.frag",
|
"spv.1.6.samplerBuffer.frag",
|
||||||
"spv.1.6.separate.frag",
|
"spv.1.6.separate.frag",
|
||||||
|
"spv.1.6.quad.frag",
|
||||||
})),
|
})),
|
||||||
FileNameAsCustomTestSuffix
|
FileNameAsCustomTestSuffix
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue