Skip to content

Commit a19c326

Browse files
author
Junda Liu
authored
[spirv] Add VK_AMD_shader_early_and_late_fragment_tests support (#4504)
1 parent 72f7643 commit a19c326

18 files changed

Lines changed: 373 additions & 4 deletions

docs/SPIR-V.rst

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,14 @@ Supported extensions
288288

289289
* SPV_KHR_16bit_storage
290290
* SPV_KHR_device_group
291+
* SPV_KHR_fragment_shading_rate
291292
* SPV_KHR_multivew
292293
* SPV_KHR_post_depth_coverage
293294
* SPV_KHR_shader_draw_parameters
294295
* SPV_EXT_descriptor_indexing
295296
* SPV_EXT_fragment_fully_covered
296-
* SPV_KHR_fragment_shading_rate
297297
* SPV_EXT_shader_stencil_support
298+
* SPV_AMD_shader_early_and_late_fragment_tests
298299
* SPV_AMD_shader_explicit_vertex_parameter
299300
* SPV_GOOGLE_hlsl_functionality1
300301
* SPV_GOOGLE_user_type
@@ -340,6 +341,40 @@ The namespace ``vk`` will be used for all Vulkan attributes:
340341
sampler (or sampled image) type with the same descriptor set and binding numbers (see
341342
`wiki page <https://github.com/microsoft/DirectXShaderCompiler/wiki/Vulkan-combined-image-sampler-type>`_
342343
for more detail).
344+
- ``early_and_late_tests``: Marks an entry point as enabling early and late depth
345+
tests. If depth is written via ``SV_Depth``, ``depth_unchanged`` must also be specified
346+
(``SV_DepthLess`` and ``SV_DepthGreater`` can be written freely). If a stencil reference
347+
value is written via ``SV_StencilRef``, one of ``stencil_ref_unchanged_front``,
348+
``stencil_ref_greater_equal_front``, or ``stencil_ref_less_equal_front`` and
349+
one of ``stencil_ref_unchanged_back``, ``stencil_ref_greater_equal_back``, or
350+
``stencil_ref_less_equal_back`` must be specified.
351+
- ``depth_unchanged``: Specifies that any depth written to ``SV_Depth`` will not
352+
invalidate the result of early depth tests. Sets the ``DepthUnchanged`` execution
353+
mode in SPIR-V. Only valid on pixel shader entry points.
354+
- ``stencil_ref_unchanged_front``: Specifies that any stencil ref written to
355+
``SV_StencilRef`` will not invalidate the result of early stencil tests when
356+
the fragment is front facing. Sets the ``StencilRefUnchangedFrontAMD`` execution
357+
mode in SPIR-V. Only valid on pixel shader entry points.
358+
- ``stencil_ref_greater_equal_front``: Specifies that any stencil ref written to
359+
``SV_StencilRef`` will be greater than or equal to the stencil reference value
360+
set by the API when the fragment is front facing. Sets the ``StencilRefGreaterFrontAMD``
361+
execution mode in SPIR-V. Only valid on pixel shader entry points.
362+
- ``stencil_ref_less_equal_front``: Specifies that any stencil ref written to
363+
``SV_StencilRef`` will be less than or equal to the stencil reference value
364+
set by the API when the fragment is front facing. Sets the ``StencilRefLessFrontAMD``
365+
execution mode in SPIR-V. Only valid on pixel shader entry points.
366+
- ``stencil_ref_unchanged_back``: Specifies that any stencil ref written to
367+
``SV_StencilRef`` will not invalidate the result of early stencil tests when
368+
the fragment is back facing. Sets the ``StencilRefUnchangedBackAMD`` execution
369+
mode in SPIR-V. Only valid on pixel shader entry points.
370+
- ``stencil_ref_greater_equal_back``: Specifies that any stencil ref written to
371+
``SV_StencilRef`` will be greater than or equal to the stencil reference value
372+
set by the API when the fragment is back facing. Sets the ``StencilRefGreaterBackAMD``
373+
execution mode in SPIR-V. Only valid on pixel shader entry points.
374+
- ``stencil_ref_less_equal_back``: Specifies that any stencil ref written to
375+
``SV_StencilRef`` will be less than or equal to the stencil reference value
376+
set by the API when the fragment is back facing. Sets the ``StencilRefLessBackAMD``
377+
execution mode in SPIR-V. Only valid on pixel shader entry points.
343378

344379
Only ``vk::`` attributes in the above list are supported. Other attributes will
345380
result in warnings and be ignored by the compiler. All C++11 attributes will

tools/clang/include/clang/Basic/Attr.td

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,62 @@ def VKShaderRecordEXT : InheritableAttr {
12011201
let LangOpts = [SPIRV];
12021202
let Documentation = [Undocumented];
12031203
}
1204+
1205+
def VKEarlyAndLateTests : InheritableAttr {
1206+
let Spellings = [CXX11<"vk", "early_and_late_tests">];
1207+
let Subjects = SubjectList<[Function], ErrorDiag>;
1208+
let LangOpts = [SPIRV];
1209+
let Documentation = [Undocumented];
1210+
}
1211+
1212+
def VKDepthUnchanged : InheritableAttr {
1213+
let Spellings = [CXX11<"vk", "depth_unchanged">];
1214+
let Subjects = SubjectList<[Function], ErrorDiag>;
1215+
let LangOpts = [SPIRV];
1216+
let Documentation = [Undocumented];
1217+
}
1218+
1219+
def VKStencilRefUnchangedFront : InheritableAttr {
1220+
let Spellings = [CXX11<"vk", "stencil_ref_unchanged_front">];
1221+
let Subjects = SubjectList<[Function], ErrorDiag>;
1222+
let LangOpts = [SPIRV];
1223+
let Documentation = [Undocumented];
1224+
}
1225+
1226+
def VKStencilRefGreaterEqualFront : InheritableAttr {
1227+
let Spellings = [CXX11<"vk", "stencil_ref_greater_equal_front">];
1228+
let Subjects = SubjectList<[Function], ErrorDiag>;
1229+
let LangOpts = [SPIRV];
1230+
let Documentation = [Undocumented];
1231+
}
1232+
1233+
def VKStencilRefLessEqualFront : InheritableAttr {
1234+
let Spellings = [CXX11<"vk", "stencil_ref_less_equal_front">];
1235+
let Subjects = SubjectList<[Function], ErrorDiag>;
1236+
let LangOpts = [SPIRV];
1237+
let Documentation = [Undocumented];
1238+
}
1239+
1240+
def VKStencilRefUnchangedBack : InheritableAttr {
1241+
let Spellings = [CXX11<"vk", "stencil_ref_unchanged_back">];
1242+
let Subjects = SubjectList<[Function], ErrorDiag>;
1243+
let LangOpts = [SPIRV];
1244+
let Documentation = [Undocumented];
1245+
}
1246+
1247+
def VKStencilRefGreaterEqualBack : InheritableAttr {
1248+
let Spellings = [CXX11<"vk", "stencil_ref_greater_equal_back">];
1249+
let Subjects = SubjectList<[Function], ErrorDiag>;
1250+
let LangOpts = [SPIRV];
1251+
let Documentation = [Undocumented];
1252+
}
1253+
1254+
def VKStencilRefLessEqualBack : InheritableAttr {
1255+
let Spellings = [CXX11<"vk", "stencil_ref_less_equal_back">];
1256+
let Subjects = SubjectList<[Function], ErrorDiag>;
1257+
let LangOpts = [SPIRV];
1258+
let Documentation = [Undocumented];
1259+
}
12041260
// SPIRV Change Ends
12051261

12061262
def C11NoReturn : InheritableAttr {

tools/clang/include/clang/SPIRV/FeatureManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ enum class Extension {
4545
EXT_shader_stencil_export,
4646
EXT_shader_viewport_index_layer,
4747
AMD_gpu_shader_half_float,
48+
AMD_shader_early_and_late_fragment_tests,
4849
AMD_shader_explicit_vertex_parameter,
4950
GOOGLE_hlsl_functionality1,
5051
GOOGLE_user_type,

tools/clang/lib/SPIRV/CapabilityVisitor.cpp

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,71 @@ bool CapabilityVisitor::visit(SpirvEntryPoint *entryPoint) {
602602
}
603603

604604
bool CapabilityVisitor::visit(SpirvExecutionMode *execMode) {
605-
if (execMode->getExecutionMode() == spv::ExecutionMode::PostDepthCoverage) {
605+
spv::ExecutionMode executionMode = execMode->getExecutionMode();
606+
SourceLocation execModeSourceLocation = execMode->getSourceLocation();
607+
SourceLocation entryPointSourceLocation =
608+
execMode->getEntryPoint()->getSourceLocation();
609+
switch (executionMode) {
610+
case spv::ExecutionMode::PostDepthCoverage:
606611
addCapability(spv::Capability::SampleMaskPostDepthCoverage,
607-
execMode->getEntryPoint()->getSourceLocation());
612+
entryPointSourceLocation);
608613
addExtension(Extension::KHR_post_depth_coverage,
609-
"[[vk::post_depth_coverage]]", execMode->getSourceLocation());
614+
"[[vk::post_depth_coverage]]", execModeSourceLocation);
615+
break;
616+
case spv::ExecutionMode::EarlyAndLateFragmentTestsAMD:
617+
addExtension(Extension::AMD_shader_early_and_late_fragment_tests,
618+
"[[vk::early_and_late_tests]]", execModeSourceLocation);
619+
break;
620+
case spv::ExecutionMode::StencilRefUnchangedFrontAMD:
621+
addCapability(spv::Capability::StencilExportEXT, entryPointSourceLocation);
622+
addExtension(Extension::AMD_shader_early_and_late_fragment_tests,
623+
"[[vk::stencil_ref_unchanged_front]]", execModeSourceLocation);
624+
addExtension(Extension::EXT_shader_stencil_export,
625+
"[[vk::stencil_ref_unchanged_front]]", execModeSourceLocation);
626+
break;
627+
case spv::ExecutionMode::StencilRefGreaterFrontAMD:
628+
addCapability(spv::Capability::StencilExportEXT, entryPointSourceLocation);
629+
addExtension(Extension::AMD_shader_early_and_late_fragment_tests,
630+
"[[vk::stencil_ref_greater_equal_front]]",
631+
execModeSourceLocation);
632+
addExtension(Extension::EXT_shader_stencil_export,
633+
"[[vk::stencil_ref_greater_equal_front]]",
634+
execModeSourceLocation);
635+
break;
636+
case spv::ExecutionMode::StencilRefLessFrontAMD:
637+
addCapability(spv::Capability::StencilExportEXT, entryPointSourceLocation);
638+
addExtension(Extension::AMD_shader_early_and_late_fragment_tests,
639+
"[[vk::stencil_ref_less_equal_front]]",
640+
execModeSourceLocation);
641+
addExtension(Extension::EXT_shader_stencil_export,
642+
"[[vk::stencil_ref_less_equal_front]]",
643+
execModeSourceLocation);
644+
break;
645+
case spv::ExecutionMode::StencilRefUnchangedBackAMD:
646+
addCapability(spv::Capability::StencilExportEXT, entryPointSourceLocation);
647+
addExtension(Extension::AMD_shader_early_and_late_fragment_tests,
648+
"[[vk::stencil_ref_unchanged_back]]", execModeSourceLocation);
649+
addExtension(Extension::EXT_shader_stencil_export,
650+
"[[vk::stencil_ref_unchanged_back]]", execModeSourceLocation);
651+
break;
652+
case spv::ExecutionMode::StencilRefGreaterBackAMD:
653+
addCapability(spv::Capability::StencilExportEXT, entryPointSourceLocation);
654+
addExtension(Extension::AMD_shader_early_and_late_fragment_tests,
655+
"[[vk::stencil_ref_greater_equal_back]]",
656+
execModeSourceLocation);
657+
addExtension(Extension::EXT_shader_stencil_export,
658+
"[[vk::stencil_ref_greater_equal_back]]",
659+
execModeSourceLocation);
660+
break;
661+
case spv::ExecutionMode::StencilRefLessBackAMD:
662+
addCapability(spv::Capability::StencilExportEXT, entryPointSourceLocation);
663+
addExtension(Extension::AMD_shader_early_and_late_fragment_tests,
664+
"[[vk::stencil_ref_less_equal_back]]", execModeSourceLocation);
665+
addExtension(Extension::EXT_shader_stencil_export,
666+
"[[vk::stencil_ref_less_equal_back]]", execModeSourceLocation);
667+
break;
668+
default:
669+
break;
610670
}
611671
return true;
612672
}

tools/clang/lib/SPIRV/FeatureManager.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) {
148148
Extension::EXT_shader_viewport_index_layer)
149149
.Case("SPV_AMD_gpu_shader_half_float",
150150
Extension::AMD_gpu_shader_half_float)
151+
.Case("SPV_AMD_shader_early_and_late_fragment_tests",
152+
Extension::AMD_shader_early_and_late_fragment_tests)
151153
.Case("SPV_AMD_shader_explicit_vertex_parameter",
152154
Extension::AMD_shader_explicit_vertex_parameter)
153155
.Case("SPV_GOOGLE_hlsl_functionality1",
@@ -201,6 +203,8 @@ const char *FeatureManager::getExtensionName(Extension symbol) {
201203
return "SPV_EXT_shader_viewport_index_layer";
202204
case Extension::AMD_gpu_shader_half_float:
203205
return "SPV_AMD_gpu_shader_half_float";
206+
case Extension::AMD_shader_early_and_late_fragment_tests:
207+
return "SPV_AMD_shader_early_and_late_fragment_tests";
204208
case Extension::AMD_shader_explicit_vertex_parameter:
205209
return "SPV_AMD_shader_explicit_vertex_parameter";
206210
case Extension::GOOGLE_hlsl_functionality1:

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11472,6 +11472,70 @@ void SpirvEmitter::processPixelShaderAttributes(const FunctionDecl *decl) {
1147211472
spv::ExecutionMode::PostDepthCoverage, {},
1147311473
decl->getLocation());
1147411474
}
11475+
if (decl->getAttr<VKEarlyAndLateTestsAttr>()) {
11476+
spvBuilder.addExecutionMode(
11477+
entryFunction, spv::ExecutionMode::EarlyAndLateFragmentTestsAMD, {},
11478+
decl->getLocation());
11479+
}
11480+
if (decl->getAttr<VKDepthUnchangedAttr>()) {
11481+
spvBuilder.addExecutionMode(entryFunction,
11482+
spv::ExecutionMode::DepthUnchanged, {},
11483+
decl->getLocation());
11484+
}
11485+
11486+
// Shaders must not specify more than one of stencil_ref_unchanged_front,
11487+
// stencil_ref_greater_equal_front, and stencil_ref_less_equal_front.
11488+
// Shaders must not specify more than one of stencil_ref_unchanged_back,
11489+
// stencil_ref_greater_equal_back,and stencil_ref_less_equal_back.
11490+
uint32_t stencilFrontAttrCount = 0, stencilBackAttrCount = 0;
11491+
if (decl->getAttr<VKStencilRefUnchangedFrontAttr>()) {
11492+
++stencilFrontAttrCount;
11493+
spvBuilder.addExecutionMode(entryFunction,
11494+
spv::ExecutionMode::StencilRefUnchangedFrontAMD,
11495+
{}, decl->getLocation());
11496+
}
11497+
if (decl->getAttr<VKStencilRefGreaterEqualFrontAttr>()) {
11498+
++stencilFrontAttrCount;
11499+
spvBuilder.addExecutionMode(entryFunction,
11500+
spv::ExecutionMode::StencilRefGreaterFrontAMD,
11501+
{}, decl->getLocation());
11502+
}
11503+
if (decl->getAttr<VKStencilRefLessEqualFrontAttr>()) {
11504+
++stencilFrontAttrCount;
11505+
spvBuilder.addExecutionMode(entryFunction,
11506+
spv::ExecutionMode::StencilRefLessFrontAMD, {},
11507+
decl->getLocation());
11508+
}
11509+
if (decl->getAttr<VKStencilRefUnchangedBackAttr>()) {
11510+
++stencilBackAttrCount;
11511+
spvBuilder.addExecutionMode(entryFunction,
11512+
spv::ExecutionMode::StencilRefUnchangedBackAMD,
11513+
{}, decl->getLocation());
11514+
}
11515+
if (decl->getAttr<VKStencilRefGreaterEqualBackAttr>()) {
11516+
++stencilBackAttrCount;
11517+
spvBuilder.addExecutionMode(entryFunction,
11518+
spv::ExecutionMode::StencilRefGreaterBackAMD,
11519+
{}, decl->getLocation());
11520+
}
11521+
if (decl->getAttr<VKStencilRefLessEqualBackAttr>()) {
11522+
++stencilBackAttrCount;
11523+
spvBuilder.addExecutionMode(entryFunction,
11524+
spv::ExecutionMode::StencilRefLessBackAMD, {},
11525+
decl->getLocation());
11526+
}
11527+
if (stencilFrontAttrCount > 1) {
11528+
emitError("Shaders must not specify more than one of "
11529+
"stencil_ref_unchanged_front, stencil_ref_greater_equal_front, "
11530+
"and stencil_ref_less_equal_front.",
11531+
{});
11532+
}
11533+
if (stencilBackAttrCount > 1) {
11534+
emitError(
11535+
"Shaders must not specify more than one of stencil_ref_unchanged_back, "
11536+
"stencil_ref_greater_equal_back, and stencil_ref_less_equal_back.",
11537+
{});
11538+
}
1147511539
}
1147611540

1147711541
void SpirvEmitter::processComputeShaderAttributes(const FunctionDecl *decl) {

tools/clang/lib/Sema/SemaHLSL.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12449,6 +12449,36 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
1244912449
case AttributeList::AT_VKPostDepthCoverage:
1245012450
declAttr = ::new (S.Context) VKPostDepthCoverageAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
1245112451
break;
12452+
case AttributeList::AT_VKEarlyAndLateTests:
12453+
declAttr = ::new (S.Context) VKEarlyAndLateTestsAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12454+
break;
12455+
case AttributeList::AT_VKDepthUnchanged:
12456+
declAttr = ::new (S.Context) VKDepthUnchangedAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12457+
break;
12458+
case AttributeList::AT_VKStencilRefUnchangedFront:
12459+
declAttr = ::new (S.Context) VKStencilRefUnchangedFrontAttr(
12460+
A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12461+
break;
12462+
case AttributeList::AT_VKStencilRefGreaterEqualFront:
12463+
declAttr = ::new (S.Context) VKStencilRefGreaterEqualFrontAttr(
12464+
A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12465+
break;
12466+
case AttributeList::AT_VKStencilRefLessEqualFront:
12467+
declAttr = ::new (S.Context) VKStencilRefLessEqualFrontAttr(
12468+
A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12469+
break;
12470+
case AttributeList::AT_VKStencilRefUnchangedBack:
12471+
declAttr = ::new (S.Context) VKStencilRefUnchangedBackAttr(
12472+
A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12473+
break;
12474+
case AttributeList::AT_VKStencilRefGreaterEqualBack:
12475+
declAttr = ::new (S.Context) VKStencilRefGreaterEqualBackAttr(
12476+
A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12477+
break;
12478+
case AttributeList::AT_VKStencilRefLessEqualBack:
12479+
declAttr = ::new (S.Context) VKStencilRefLessEqualBackAttr(
12480+
A.getRange(), S.Context, A.getAttributeSpellingListIndex());
12481+
break;
1245212482
case AttributeList::AT_VKShaderRecordNV:
1245312483
declAttr = ::new (S.Context) VKShaderRecordNVAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
1245412484
break;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %dxc -T ps_6_0 -E main
2+
3+
// CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests"
4+
// CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD
5+
// CHECK: OpExecutionMode %main DepthUnchanged
6+
7+
[[vk::early_and_late_tests]]
8+
[[vk::depth_unchanged]]
9+
void main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %dxc -T ps_6_0 -E main
2+
3+
// CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests"
4+
// CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD
5+
6+
[[vk::early_and_late_tests]]
7+
void main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %dxc -T ps_6_0 -E main
2+
3+
// CHECK: error: Shaders must not specify more than one of stencil_ref_unchanged_back, stencil_ref_greater_equal_back, and stencil_ref_less_equal_back.
4+
5+
[[vk::early_and_late_tests]]
6+
[[vk::stencil_ref_less_equal_back]]
7+
[[vk::stencil_ref_greater_equal_back]]
8+
void main() {}

0 commit comments

Comments
 (0)