Skip to content

Commit 104ff64

Browse files
committed
Fix per-primitive output for spirv mesh shaders
Adds a `perprimitive` interpolation mode which corresponds to `perprimitiveEXT` from `SPV_EXT_mesh_shader`. Adds a `perprimitive` modifier to apply the interpolation mode. Replaces use of `kIROp_GLSLPrimitivesRateDecoration` with new `perprimitive` interpolation mode.
1 parent b649a81 commit 104ff64

11 files changed

+65
-29
lines changed

source/slang/core.meta.slang

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ syntax globallycoherent : GloballyCoherentModifier;
4141
///
4242
syntax pervertex : PerVertexModifier;
4343

44+
/// Modifier to disable inteprolation and force per-primitive passing of a varying attribute.
45+
syntax perprimitive : PerPrimitiveModifier;
46+
4447
/// Modifier to indicate a buffer or texture element type is
4548
/// backed by data in an unsigned normalized format.
4649
///

source/slang/slang-ast-modifier.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,13 @@ class PerVertexModifier : public InterpolationModeModifier
711711
FIDDLE(...)
712712
};
713713

714+
/// Slang-defined `perprimitive` modifier
715+
FIDDLE()
716+
class PerPrimitiveModifier : public InterpolationModeModifier
717+
{
718+
FIDDLE(...)
719+
};
720+
714721

715722
// HLSL `precise` modifier
716723
FIDDLE()

source/slang/slang-check-modifier.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,7 @@ ASTNodeType getModifierConflictGroupKind(ASTNodeType modifierType)
13741374
case ASTNodeType::HLSLSampleModifier:
13751375
case ASTNodeType::HLSLCentroidModifier:
13761376
case ASTNodeType::PerVertexModifier:
1377+
case ASTNodeType::PerPrimitiveModifier:
13771378
return ASTNodeType::InterpolationModeModifier;
13781379

13791380
case ASTNodeType::PrefixModifier:
@@ -1466,6 +1467,7 @@ bool isModifierAllowedOnDecl(bool isGLSLInput, ASTNodeType modifierType, Decl* d
14661467
case ASTNodeType::HLSLSampleModifier:
14671468
case ASTNodeType::HLSLCentroidModifier:
14681469
case ASTNodeType::PerVertexModifier:
1470+
case ASTNodeType::PerPrimitiveModifier:
14691471
case ASTNodeType::HLSLUniformModifier:
14701472
case ASTNodeType::DynamicUniformModifier:
14711473
return (as<VarDeclBase>(decl) &&

source/slang/slang-emit-glsl.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ void GLSLSourceEmitter::_requireFragmentShaderBarycentric()
160160
m_glslExtensionTracker->requireVersion(ProfileVersion::GLSL_450);
161161
}
162162

163+
void GLSLSourceEmitter::_requireMeshShader()
164+
{
165+
m_glslExtensionTracker->requireExtension(
166+
UnownedStringSlice::fromLiteral("GL_EXT_mesh_shader"));
167+
m_glslExtensionTracker->requireVersion(ProfileVersion::GLSL_450);
168+
}
163169

164170
void GLSLSourceEmitter::_requireGLSLExtension(const UnownedStringSlice& name)
165171
{
@@ -3632,6 +3638,17 @@ bool GLSLSourceEmitter::_maybeEmitInterpolationModifierText(
36323638
m_writer->emit("flat ");
36333639
}
36343640
return true;
3641+
case IRInterpolationMode::PerPrimitive:
3642+
if (stage == Stage::Fragment && isInput)
3643+
{
3644+
_requireMeshShader();
3645+
m_writer->emit("perprimitiveEXT ");
3646+
}
3647+
else
3648+
{
3649+
m_writer->emit("flat ");
3650+
}
3651+
return true;
36353652
default:
36363653
return false;
36373654
}
@@ -3676,6 +3693,16 @@ void GLSLSourceEmitter::emitInterpolationModifiersImpl(
36763693
}
36773694
}
36783695
break;
3696+
3697+
case IRInterpolationMode::PerPrimitive:
3698+
if (stage == Stage::Fragment)
3699+
{
3700+
if (isInput)
3701+
{
3702+
_requireMeshShader();
3703+
}
3704+
}
3705+
break;
36793706
}
36803707
}
36813708

source/slang/slang-emit-glsl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ class GLSLSourceEmitter : public CLikeSourceEmitter
176176

177177
void _requireFragmentShaderBarycentric();
178178

179+
void _requireMeshShader();
180+
179181
void _emitSpecialFloatImpl(IRType* type, const char* valueExpr);
180182

181183
void emitAtomicImageCoord(IRImageSubscript* operand);

source/slang/slang-emit-hlsl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "../core/slang-writer.h"
55
#include "slang-emit-source-writer.h"
6+
#include "slang-ir-insts.h"
67
#include "slang-ir-util.h"
78
#include "slang-mangled-lexer.h"
89

@@ -1771,6 +1772,7 @@ static UnownedStringSlice _getInterpolationModifierText(IRInterpolationMode mode
17711772
switch (mode)
17721773
{
17731774
case IRInterpolationMode::PerVertex:
1775+
case IRInterpolationMode::PerPrimitive:
17741776
case IRInterpolationMode::NoInterpolation:
17751777
return UnownedStringSlice::fromLiteral("nointerpolation");
17761778
case IRInterpolationMode::NoPerspective:

source/slang/slang-emit-metal.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,7 @@ static UnownedStringSlice _getInterpolationModifierText(IRInterpolationMode mode
15271527
switch (mode)
15281528
{
15291529
case IRInterpolationMode::PerVertex:
1530+
case IRInterpolationMode::PerPrimitive:
15301531
case IRInterpolationMode::NoInterpolation:
15311532
return UnownedStringSlice::fromLiteral("[[flat]]");
15321533
case IRInterpolationMode::NoPerspective:

source/slang/slang-emit-spirv.cpp

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2900,6 +2900,13 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
29002900
varInst,
29012901
SpvDecorationNoPerspective);
29022902
return true;
2903+
case IRInterpolationMode::PerPrimitive:
2904+
emitOpDecorate(
2905+
getSection(SpvLogicalSectionID::Annotations),
2906+
nullptr,
2907+
varInst,
2908+
SpvDecorationPerPrimitiveEXT);
2909+
return true;
29032910
case IRInterpolationMode::Linear:
29042911
return true;
29052912
case IRInterpolationMode::Sample:
@@ -2920,22 +2927,6 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
29202927
return false;
29212928
}
29222929
}
2923-
void emitSystemVarDecoration(IRInst* var, SpvInst* varInst)
2924-
{
2925-
for (auto decor : var->getDecorations())
2926-
{
2927-
switch (decor->getOp())
2928-
{
2929-
case kIROp_GLSLPrimitivesRateDecoration:
2930-
emitOpDecorate(
2931-
getSection(SpvLogicalSectionID::Annotations),
2932-
decor,
2933-
varInst,
2934-
SpvDecorationPerPrimitiveEXT);
2935-
break;
2936-
}
2937-
}
2938-
}
29392930

29402931
void emitVarLayout(IRInst* var, SpvInst* varInst, IRVarLayout* layout)
29412932
{
@@ -3084,20 +3075,11 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
30843075

30853076
for (auto decor : var->getDecorations())
30863077
{
3087-
switch (decor->getOp())
3078+
if (decor->getOp() == kIROp_RequireSPIRVDescriptorIndexingExtensionDecoration)
30883079
{
3089-
case kIROp_GLSLPrimitivesRateDecoration:
3090-
emitOpDecorate(
3091-
getSection(SpvLogicalSectionID::Annotations),
3092-
decor,
3093-
varInst,
3094-
SpvDecorationPerPrimitiveEXT);
3095-
break;
3096-
case kIROp_RequireSPIRVDescriptorIndexingExtensionDecoration:
30973080
ensureExtensionDeclarationBeforeSpv15(
30983081
UnownedStringSlice("SPV_EXT_descriptor_indexing"));
30993082
requireSPIRVCapability(SpvCapabilityRuntimeDescriptorArray);
3100-
break;
31013083
}
31023084
}
31033085
}
@@ -3278,7 +3260,6 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
32783260
}
32793261
if (auto systemValInst = maybeEmitSystemVal(param))
32803262
{
3281-
emitSystemVarDecoration(param, systemValInst);
32823263
registerInst(param, systemValInst);
32833264
return systemValInst;
32843265
}

source/slang/slang-ir-glsl-legalize.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "slang-extension-tracker.h"
55
#include "slang-ir-clone.h"
66
#include "slang-ir-inst-pass-base.h"
7+
#include "slang-ir-insts-enum.h"
78
#include "slang-ir-insts.h"
89
#include "slang-ir-single-return.h"
910
#include "slang-ir-specialize-function-call.h"
@@ -1011,7 +1012,7 @@ void createVarLayoutForLegalizedGlobalParam(
10111012

10121013
if (declarator && declarator->flavor == GlobalVaryingDeclarator::Flavor::meshOutputPrimitives)
10131014
{
1014-
builder->addDecoration(globalParam, kIROp_GLSLPrimitivesRateDecoration);
1015+
builder->addInterpolationModeDecoration(globalParam, IRInterpolationMode::PerPrimitive);
10151016
}
10161017

10171018
if (systemValueInfo)
@@ -3063,7 +3064,7 @@ static void legalizeMeshOutputParam(
30633064
builder->addImportDecoration(blockParam, UnownedStringSlice(arrayName));
30643065
if (isPerPrimitive)
30653066
{
3066-
builder->addDecoration(blockParam, kIROp_GLSLPrimitivesRateDecoration);
3067+
builder->addInterpolationModeDecoration(blockParam, IRInterpolationMode::PerPrimitive);
30673068
}
30683069
// // While this is probably a correct thing to do, LRK::VaryingOutput
30693070
// // isn't really used for redeclaraion of builtin outputs, and assumes
@@ -3710,6 +3711,11 @@ void legalizeEntryPointParameterForGLSL(
37103711
tryReplaceUsesOfStageInput(context, globalValue, pp);
37113712
for (auto dec : pp->getDecorations())
37123713
{
3714+
if (dec->getOp() == kIROp_GlobalInputDecoration)
3715+
{
3716+
fprintf(stderr, "global input!\n");
3717+
}
3718+
37133719
if (dec->getOp() != kIROp_GlobalVariableShadowingGlobalParameterDecoration)
37143720
continue;
37153721
auto globalVar = dec->getOperand(0);

source/slang/slang-ir-insts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ enum class IRInterpolationMode
161161
Sample,
162162

163163
PerVertex,
164+
PerPrimitive,
164165
};
165166

166167
enum class IRTargetBuiltinVarName

0 commit comments

Comments
 (0)