Skip to content

Commit ed1502e

Browse files
authored
Support PerVertexKHR decorated input and SV_Barycentric (microsoft#5649)
1. Replace extension AMD_shader_explicit_vertex_parameter with KHR_fragment_shading_barycentric as they define same semantic. 2. Support new usage of SV_BaryCentrics and PerVertexKHR decorated input. 3. For per-vertex inputs, they will be used as an array if a shader call new intrinsic GetAttributeAtVertex explicitly. 4. Support mixed deprecate usage of `nointerpolation` qualifier. When use non-interpolated inputs outside new intrinsic, it will be treated as accessing to first provoking vertex : data[0]. But it will still be treated as an array if used as a function call's argument. 5. As now we allow mixed usage of this kind of inputs, add spirv instruction operand replacement in DXC. A new visitor will replace normal access to those inputs with a new AccessChain instruction targets its first element. 6. For bool and bool vector type, we reconstruct a new bool/boolVec type array in entry function wrapper.
1 parent 64030a4 commit ed1502e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1545
-319
lines changed

docs/SPIR-V.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,10 @@ Supported extensions
297297
* SPV_EXT_mesh_shader
298298
* SPV_EXT_shader_stencil_support
299299
* SPV_AMD_shader_early_and_late_fragment_tests
300-
* SPV_AMD_shader_explicit_vertex_parameter
301300
* SPV_GOOGLE_hlsl_functionality1
302301
* SPV_GOOGLE_user_type
303302
* SPV_NV_mesh_shader
303+
* SPV_KHR_fragment_shading_barycentric
304304

305305
Vulkan specific attributes
306306
--------------------------
@@ -1583,7 +1583,7 @@ some system-value (SV) semantic strings will be translated into SPIR-V
15831583
+---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
15841584
| SV_StencilRef | PSOut | ``FragStencilRefEXT`` | N/A | ``StencilExportEXT`` |
15851585
+---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
1586-
| SV_Barycentrics | PSIn | ``BaryCoord*AMD`` | N/A | ``Shader`` |
1586+
| SV_Barycentrics | PSIn | ``BaryCoord*KHR`` | N/A | ``FragmentBarycentricKHR`` |
15871587
+---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
15881588
| | GSOut | ``Layer`` | N/A | ``Geometry`` |
15891589
| +-------------+----------------------------------------+-----------------------+-----------------------------+

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ enum class Extension {
4949
EXT_shader_viewport_index_layer,
5050
AMD_gpu_shader_half_float,
5151
AMD_shader_early_and_late_fragment_tests,
52-
AMD_shader_explicit_vertex_parameter,
5352
GOOGLE_hlsl_functionality1,
5453
GOOGLE_user_type,
5554
NV_ray_tracing,
@@ -59,6 +58,7 @@ enum class Extension {
5958
KHR_physical_storage_buffer,
6059
KHR_vulkan_memory_model,
6160
NV_compute_shader_derivatives,
61+
KHR_fragment_shader_barycentric,
6262
Unknown,
6363
};
6464

tools/clang/include/clang/SPIRV/SpirvBuilder.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ class SpirvBuilder {
8686
/// \brief Creates and registers a function parameter of the given pointer
8787
/// type in the current function and returns its pointer.
8888
SpirvFunctionParameter *addFnParam(QualType ptrType, bool isPrecise,
89-
SourceLocation, llvm::StringRef name = "");
89+
bool isNointerp, SourceLocation,
90+
llvm::StringRef name = "");
9091

9192
/// \brief Creates a local variable of the given type in the current
9293
/// function and returns it.
@@ -95,6 +96,7 @@ class SpirvBuilder {
9596
/// this method for the variable itself.
9697
SpirvVariable *addFnVar(QualType valueType, SourceLocation,
9798
llvm::StringRef name = "", bool isPrecise = false,
99+
bool isNointerp = false,
98100
SpirvInstruction *init = nullptr);
99101

100102
/// \brief Ends building of the current function. All basic blocks constructed
@@ -628,7 +630,7 @@ class SpirvBuilder {
628630
/// constructed in this method.
629631
SpirvVariable *addStageIOVar(QualType type, spv::StorageClass storageClass,
630632
llvm::StringRef name, bool isPrecise,
631-
SourceLocation loc);
633+
bool isNointerp, SourceLocation loc);
632634

633635
/// \brief Adds a stage builtin variable whose value is of the given type.
634636
///
@@ -646,12 +648,12 @@ class SpirvBuilder {
646648
/// constructed in this method.
647649
SpirvVariable *
648650
addModuleVar(QualType valueType, spv::StorageClass storageClass,
649-
bool isPrecise, llvm::StringRef name = "",
651+
bool isPrecise, bool isNointerp, llvm::StringRef name = "",
650652
llvm::Optional<SpirvInstruction *> init = llvm::None,
651653
SourceLocation loc = {});
652654
SpirvVariable *
653655
addModuleVar(const SpirvType *valueType, spv::StorageClass storageClass,
654-
bool isPrecise, llvm::StringRef name = "",
656+
bool isPrecise, bool isNointerp, llvm::StringRef name = "",
655657
llvm::Optional<SpirvInstruction *> init = llvm::None,
656658
SourceLocation loc = {});
657659

@@ -711,6 +713,9 @@ class SpirvBuilder {
711713
void decoratePerTaskNV(SpirvInstruction *target, uint32_t offset,
712714
SourceLocation);
713715

716+
/// \brief Decorates the given target with PerVertexKHR
717+
void decoratePerVertexKHR(SpirvInstruction *argInst, SourceLocation);
718+
714719
/// \brief Decorates the given target with Coherent
715720
void decorateCoherent(SpirvInstruction *target, SourceLocation);
716721

@@ -758,6 +763,13 @@ class SpirvBuilder {
758763
const SpirvPointerType *
759764
getPhysicalStorageBufferType(const SpirvType *pointee);
760765

766+
void setPerVertexInterpMode(bool b);
767+
bool isPerVertexInterpMode();
768+
769+
void addPerVertexStgInputFuncVarEntry(SpirvInstruction *k,
770+
SpirvInstruction *v);
771+
SpirvInstruction *getPerVertexStgInput(SpirvInstruction *k);
772+
761773
public:
762774
std::vector<uint32_t> takeModule();
763775

@@ -863,6 +875,10 @@ class SpirvBuilder {
863875
/// clone variables. We need it to avoid multiple clone variables for the same
864876
/// CTBuffer.
865877
llvm::DenseMap<SpirvVariable *, SpirvVariable *> fxcCTBufferToClone;
878+
879+
/// Mapping of a temporary stage parameter variable to real stage input
880+
/// variables, only when the declaration has attribute `nointerpolation`
881+
llvm::DenseMap<SpirvInstruction *, SpirvInstruction *> perVertexInputVarMap;
866882
};
867883

868884
void SpirvBuilder::requireCapability(spv::Capability cap, SourceLocation loc) {

tools/clang/include/clang/SPIRV/SpirvFunction.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class SpirvFunction {
5959
return parameters;
6060
}
6161

62+
// Gets the vector of variables.
63+
std::vector<SpirvVariable *> getVariables() { return variables; }
64+
6265
// Sets the SPIR-V type of the function
6366
void setFunctionType(SpirvType *type) { fnType = type; }
6467
// Returns the SPIR-V type of the function
@@ -98,6 +101,21 @@ class SpirvFunction {
98101
basicBlocks[0]->addFirstInstruction(inst);
99102
}
100103

104+
/// Adds instructions to a cache array.
105+
void addToInstructionCache(SpirvInstruction *inst) {
106+
instructionsCache.push_back(inst);
107+
}
108+
109+
/// Adds cached instructions to the front of current function.
110+
void addInstrCacheToFront() {
111+
int cacheSize = instructionsCache.size();
112+
for (int i = 0; i < cacheSize; i++) {
113+
auto *inst = instructionsCache.back();
114+
addFirstInstruction(inst);
115+
instructionsCache.pop_back();
116+
}
117+
instructionsCache.clear();
118+
}
101119
/// Legalization-specific code
102120
///
103121
/// Note: the following methods are used for properly handling aliasing.
@@ -122,6 +140,15 @@ class SpirvFunction {
122140
return parameters[0]->getDebugName() == "param.this";
123141
}
124142

143+
/// Get or set a record for relationship between
144+
/// a function parameter and variable within current function.
145+
void addFuncParamVarEntry(SpirvInstruction *v, SpirvInstruction *p) {
146+
funcVarParamMap[v] = p;
147+
}
148+
SpirvInstruction *getMappedFuncParam(SpirvInstruction *v) {
149+
return funcVarParamMap.lookup(v);
150+
}
151+
125152
private:
126153
uint32_t functionId; ///< This function's <result-id>
127154
QualType astReturnType; ///< The return type
@@ -130,6 +157,9 @@ class SpirvFunction {
130157
bool relaxedPrecision; ///< Whether the return type is at relaxed precision
131158
bool precise; ///< Whether the return value is 'precise'
132159
bool noInline; ///< The function is marked as no inline
160+
///< An instructions cache vector. Would be used to help insert instructions
161+
///< at the beginning of a function.
162+
std::vector<SpirvInstruction *> instructionsCache;
133163

134164
/// Legalization-specific code
135165
///
@@ -164,6 +194,9 @@ class SpirvFunction {
164194

165195
/// DebugDeclare instructions for parameters to this function.
166196
llvm::SmallVector<SpirvDebugDeclare *, 8> debugDeclares;
197+
198+
/// Record relationship between a function parameter and its mapped variable.
199+
llvm::DenseMap<SpirvInstruction *, SpirvInstruction *> funcVarParamMap;
167200
};
168201

169202
} // end namespace spirv

0 commit comments

Comments
 (0)