summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-emit-cpp.cpp4
-rw-r--r--source/slang/slang-emit-glsl.cpp67
-rw-r--r--source/slang/slang-emit-hlsl.cpp35
-rw-r--r--source/slang/slang-ir-entry-point-uniforms.cpp2
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp44
-rw-r--r--source/slang/slang-ir-inst-defs.h21
-rw-r--r--source/slang/slang-ir-insts.h36
-rw-r--r--source/slang/slang-lower-to-ir.cpp43
-rw-r--r--tests/ir/string-literal.slang.expected2
9 files changed, 183 insertions, 71 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 1f38512b4..3727bf45e 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -2343,7 +2343,7 @@ void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPre
{
String name = getName(inst);
- if (inst->findDecorationImpl(kIROp_EntryPointDecoration))
+ if (inst->findDecorationImpl(kIROp_EntryPointParamDecoration))
{
// It's an entry point parameter
// The parameter is held in a struct so always deref
@@ -2695,7 +2695,7 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module)
{
auto inst = action.inst;
- if (inst->findDecorationImpl(kIROp_EntryPointDecoration))
+ if (inst->findDecorationImpl(kIROp_EntryPointParamDecoration))
{
// Should only be one instruction marked this way
SLANG_ASSERT(entryPointGlobalParams == nullptr);
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index e43d41d5c..78d34d649 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -654,7 +654,14 @@ void GLSLSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniform
void GLSLSourceEmitter::emitEntryPointAttributesImpl(IRFunc* irFunc, EntryPointLayout* entryPointLayout)
{
- auto profile = entryPointLayout->profile;
+ SLANG_UNUSED(entryPointLayout);
+
+ IREntryPointDecoration* entryPointDecor = irFunc->findDecoration<IREntryPointDecoration>();
+ SLANG_ASSERT(entryPointDecor);
+
+ //auto profile = entryPointLayout->profile;
+
+ auto profile = entryPointDecor->getProfile();
auto stage = profile.GetStage();
switch (stage)
@@ -695,50 +702,36 @@ void GLSLSourceEmitter::emitEntryPointAttributesImpl(IRFunc* irFunc, EntryPointL
m_writer->emit(") in;\n");
}
- for (auto pp : entryPointLayout->getFuncDecl()->GetParameters())
+ // These decorations were moved from the parameters to the entry point by ir-glsl-legalize.
+ // The actual parameters have become potentially multiple global parameters.
+ if (auto decor = irFunc->findDecoration<IRGeometryPrimitiveTypeDecoration>())
{
- if (auto inputPrimitiveTypeModifier = pp->FindModifier<HLSLGeometryShaderInputPrimitiveTypeModifier>())
+ switch (decor->op)
{
- if (as<HLSLTriangleModifier>(inputPrimitiveTypeModifier))
- {
- m_writer->emit("layout(triangles) in;\n");
- }
- else if (as<HLSLLineModifier>(inputPrimitiveTypeModifier))
- {
- m_writer->emit("layout(lines) in;\n");
- }
- else if (as<HLSLLineAdjModifier>(inputPrimitiveTypeModifier))
- {
- m_writer->emit("layout(lines_adjacency) in;\n");
- }
- else if (as<HLSLPointModifier>(inputPrimitiveTypeModifier))
+ case kIROp_TrianglePrimitiveTypeDecoration: m_writer->emit("layout(triangles) in;\n"); break;
+ case kIROp_LinePrimitiveTypeDecoration: m_writer->emit("layout(lines) in;\n"); break;
+ case kIROp_LineAdjPrimitiveTypeDecoration: m_writer->emit("layout(lines_adjacency) in;\n"); break;
+ case kIROp_PointPrimitiveTypeDecoration: m_writer->emit("layout(points) in;\n"); break;
+ case kIROp_TriangleAdjPrimitiveTypeDecoration: m_writer->emit("layout(triangles_adjacency) in;\n"); break;
+ default:
{
- m_writer->emit("layout(points) in;\n");
- }
- else if (as<HLSLTriangleAdjModifier>(inputPrimitiveTypeModifier))
- {
- m_writer->emit("layout(triangles_adjacency) in;\n");
- }
- }
-
- if (auto outputStreamType = as<HLSLStreamOutputType>(pp->type))
- {
- if (as<HLSLTriangleStreamType>(outputStreamType))
- {
- m_writer->emit("layout(triangle_strip) out;\n");
- }
- else if (as<HLSLLineStreamType>(outputStreamType))
- {
- m_writer->emit("layout(line_strip) out;\n");
- }
- else if (as<HLSLPointStreamType>(outputStreamType))
- {
- m_writer->emit("layout(points) out;\n");
+ SLANG_ASSERT(!"Unknown primitive type");
}
}
}
+ if (auto decor = irFunc->findDecoration<IRStreamOutputTypeDecoration>())
+ {
+ IRType* type = decor->getStreamType();
+ switch (type->op)
+ {
+ case kIROp_HLSLPointStreamType: m_writer->emit("layout(points) out;\n"); break;
+ case kIROp_HLSLLineStreamType: m_writer->emit("layout(line_strip) out;\n"); break;
+ case kIROp_HLSLTriangleStreamType: m_writer->emit("layout(triangle_strip) out;\n"); break;
+ default: SLANG_ASSERT(!"Unknown stream out type");
+ }
+ }
}
break;
case Stage::Pixel:
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index a5c4ae088..0ce3a682d 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -222,8 +222,13 @@ void HLSLSourceEmitter::_emitHLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor
void HLSLSourceEmitter::_emitHLSLEntryPointAttributes(IRFunc* irFunc, EntryPointLayout* entryPointLayout)
{
+ SLANG_UNUSED(entryPointLayout);
+
+ IREntryPointDecoration* entryPointDecor = irFunc->findDecoration<IREntryPointDecoration>();
+ SLANG_ASSERT(entryPointDecor);
+
auto profile = m_effectiveProfile;
- auto stage = entryPointLayout->profile.GetStage();
+ auto stage = entryPointDecor->getProfile().GetStage();
if (profile.getFamily() == ProfileFamily::DX)
{
@@ -668,28 +673,16 @@ void HLSLSourceEmitter::emitSemanticsImpl(IRInst* inst)
void HLSLSourceEmitter::emitSimpleFuncParamImpl(IRParam* param)
{
- if (auto layoutDecor = param->findDecoration<IRLayoutDecoration>())
+ if (auto decor = param->findDecoration<IRGeometryPrimitiveTypeDecoration>())
{
- Layout* layout = layoutDecor->getLayout();
- VarLayout* varLayout = as<VarLayout>(layout);
-
- if (varLayout)
+ switch (decor->op)
{
- auto var = varLayout->getVariable();
-
- if (auto primTypeModifier = var->FindModifier<HLSLGeometryShaderInputPrimitiveTypeModifier>())
- {
- if (as<HLSLTriangleModifier>(primTypeModifier))
- m_writer->emit("triangle ");
- else if (as<HLSLPointModifier>(primTypeModifier))
- m_writer->emit("point ");
- else if (as<HLSLLineModifier>(primTypeModifier))
- m_writer->emit("line ");
- else if (as<HLSLLineAdjModifier>(primTypeModifier))
- m_writer->emit("lineadj ");
- else if (as<HLSLTriangleAdjModifier>(primTypeModifier))
- m_writer->emit("triangleadj ");
- }
+ case kIROp_TrianglePrimitiveTypeDecoration: m_writer->emit("triangle "); break;
+ case kIROp_PointPrimitiveTypeDecoration: m_writer->emit("point "); break;
+ case kIROp_LinePrimitiveTypeDecoration: m_writer->emit("line "); break;
+ case kIROp_LineAdjPrimitiveTypeDecoration: m_writer->emit("lineadj "); break;
+ case kIROp_TriangleAdjPrimitiveTypeDecoration: m_writer->emit("triangleadj "); break;
+ default: SLANG_ASSERT(!"Unknown primitive type"); break;
}
}
diff --git a/source/slang/slang-ir-entry-point-uniforms.cpp b/source/slang/slang-ir-entry-point-uniforms.cpp
index 670327446..9e36c0853 100644
--- a/source/slang/slang-ir-entry-point-uniforms.cpp
+++ b/source/slang/slang-ir-entry-point-uniforms.cpp
@@ -250,7 +250,7 @@ struct MoveEntryPointUniformParametersToGlobalScope
globalParam = builder->createGlobalParam(paramStructType);
// Mark that this global comes from the entry point
- builder->addEntryPointDecoration(globalParam);
+ builder->addDecoration(globalParam, kIROp_EntryPointParamDecoration);
}
// No matter what, the global shader parameter should have the layout
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index 11456976e..5f5db5f01 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -1246,6 +1246,48 @@ void legalizeEntryPointParameterForGLSL(
auto builder = context->getBuilder();
auto stage = context->getStage();
+ // (JS): In the legalization process parameters are moved from the entry point.
+ // So when we get to emit we have a problem in that we can't use parameters to find important decorations
+ // And in the future we will not have front end 'Layout' available. To work around this, we take the
+ // decorations that need special handling from parameters and put them on the IRFunc.
+ //
+ // This is only appropriate of course if there is only one of each for all parameters...
+ // which is what current emit code assumes, but may not be more generally applicable.
+ if (auto geomDecor = pp->findDecoration<IRGeometryPrimitiveTypeDecoration>())
+ {
+ if (!func->findDecoration<IRGeometryPrimitiveTypeDecoration>())
+ {
+ builder->addDecoration(func, geomDecor->op);
+ }
+ else
+ {
+ SLANG_UNEXPECTED("Only expected a single parameter to have IRGeometryPrimitiveTypeDecoration decoration");
+ }
+ }
+
+ // There *can* be multiple streamout parameters, to an entry point (points if nothing else)
+ {
+ IRType* type = pp->getFullType();
+ // Strip out type
+ if (auto outType = as<IROutTypeBase>(type))
+ {
+ type = outType->getValueType();
+ }
+
+ if (auto streamType = as<IRHLSLStreamOutputType>(type))
+ {
+ if (auto decor = func->findDecoration<IRStreamOutputTypeDecoration>())
+ {
+ // If it has the same stream out type, we *may* be ok (might not work for all types of streams)
+ SLANG_ASSERT(decor->getStreamType()->op == streamType->op);
+ }
+ else
+ {
+ builder->addDecoration(func, kIROp_StreamOutputTypeDecoration, streamType);
+ }
+ }
+ }
+
// We need to create a global variable that will replace the parameter.
// It seems superficially obvious that the variable should have
// the same type as the parameter.
@@ -1289,8 +1331,6 @@ void legalizeEntryPointParameterForGLSL(
// For now we will just try to deal with `Append` calls
// directly in this function.
-
-
for( auto bb = func->getFirstBlock(); bb; bb = bb->getNextBlock() )
{
for( auto ii = bb->getFirstInst(); ii; ii = ii->getNextInst() )
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index b586aa5bc..dee0ef2f8 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -422,9 +422,24 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
INST(InstanceDecoration, instance, 1, 0)
INST(NumThreadsDecoration, numThreads, 3, 0)
- /// An `[entryPoint]` decoration marks a function that represents a shader entry point.
- /// Also used in some scenarios mark parameters that are moved from entry point parameters to global params as coming from the entry point.
- INST(EntryPointDecoration, entryPoint, 0, 0)
+ // Added to IRParam parameters to an entry point
+ INST(GeometryPrimitiveTypeDecoration, geometryPrimitiveTypeDecoration, 1, 0)
+
+ /* GeometryPrimitiveTypeDecoration */
+ INST(PointPrimitiveTypeDecoration, pointPrimitiveType, 0, 0)
+ INST(LinePrimitiveTypeDecoration, linePrimitiveType, 0, 0)
+ INST(TrianglePrimitiveTypeDecoration, trianglePrimitiveType, 0, 0)
+ INST(LineAdjPrimitiveTypeDecoration, lineAdjPrimitiveType, 0, 0)
+ INST(TriangleAdjPrimitiveTypeDecoration, triangleAdjPrimitiveType, 0, 0)
+ INST_RANGE(GeometryPrimitiveTypeDecoration, PointPrimitiveTypeDecoration, TriangleAdjPrimitiveTypeDecoration)
+
+ INST(StreamOutputTypeDecoration, streamOutputTypeDecoration, 1, 0)
+
+ /// An `[entryPoint]` decoration marks a function that represents a shader entry point
+ INST(EntryPointDecoration, entryPoint, 1, 0)
+
+ /// Used to mark parameters that are moved from entry point parameters to global params as coming from the entry point.
+ INST(EntryPointParamDecoration, entryPointParam, 0, 0)
/// A `[dependsOn(x)]` decoration indicates that the parent instruction depends on `x`
/// even if it does not otherwise reference it.
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 9dc80beac..8122fb7b6 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -287,13 +287,43 @@ struct IRNumThreadsDecoration : IRDecoration
IRIntLit* getZ() { return cast<IRIntLit>(getOperand(2)); }
};
+struct IREntryPointDecoration : IRDecoration
+{
+ enum { kOp = kIROp_EntryPointDecoration };
+ IR_LEAF_ISA(EntryPointDecoration)
+
+ IRIntLit* getProfileInst() { return cast<IRIntLit>(getOperand(0)); }
+ Profile getProfile() { return Profile(Profile::RawVal(GetIntVal(getProfileInst()))); }
+};
+
+struct IRGeometryPrimitiveTypeDecoration: IRDecoration
+{
+ enum { kOp = kIROp_GeometryPrimitiveTypeDecoration };
+ IR_PARENT_ISA(GeometryPrimitiveTypeDecoration)
+};
+
+IR_SIMPLE_DECORATION(PointPrimitiveTypeDecoration)
+IR_SIMPLE_DECORATION(LinePrimitiveTypeDecoration)
+IR_SIMPLE_DECORATION(TrianglePrimitiveTypeDecoration)
+IR_SIMPLE_DECORATION(LineAdjPrimitiveTypeDecoration)
+IR_SIMPLE_DECORATION(TriangleAdjPrimitiveTypeDecoration)
+
+ /// This is a bit of a hack. The problem is that when GLSL legalization takes place
/// A decoration that marks a value as having linkage.
///
/// A value with linkage is either exported from its module,
/// or will have a definition imported from another module.
/// In either case, it requires a mangled name to use when
/// matching imports and exports.
- ///
+struct IRStreamOutputTypeDecoration : IRDecoration
+{
+ enum { kOp = kIROp_StreamOutputTypeDecoration };
+ IR_LEAF_ISA(StreamOutputTypeDecoration)
+
+ IRHLSLStreamOutputType* getStreamType() { return cast<IRHLSLStreamOutputType>(getOperand(0)); }
+};
+
+
struct IRLinkageDecoration : IRDecoration
{
IR_PARENT_ISA(LinkageDecoration)
@@ -1368,9 +1398,9 @@ struct IRBuilder
addDecoration(value, kIROp_ExportDecoration, getStringValue(mangledName));
}
- void addEntryPointDecoration(IRInst* value)
+ void addEntryPointDecoration(IRInst* value, Profile profile)
{
- addDecoration(value, kIROp_EntryPointDecoration);
+ addDecoration(value, kIROp_EntryPointDecoration, getIntValue(getIntType(), profile.raw));
}
void addKeepAliveDecoration(IRInst* value)
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index a622c9802..cec2bd988 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -6338,7 +6338,48 @@ static void lowerFrontEndEntryPointToIR(
{
instToDecorate = findGenericReturnVal(irGeneric);
}
- builder->addEntryPointDecoration(instToDecorate);
+ builder->addEntryPointDecoration(instToDecorate, entryPoint->getProfile());
+
+ // Go through the entry point parameters creating decorations from layout as appropriate
+ {
+ FilteredMemberList<ParamDecl> params = entryPointFuncDecl->GetParameters();
+
+ IRGlobalValueWithParams* valueWithParams = as<IRGlobalValueWithParams>(instToDecorate);
+ if (valueWithParams)
+ {
+ IRParam* irParam = valueWithParams->getFirstParam();
+
+ for (auto param : params)
+ {
+ if (auto modifier = param->FindModifier<HLSLGeometryShaderInputPrimitiveTypeModifier>())
+ {
+ IROp op = kIROp_Invalid;
+
+ if (as<HLSLTriangleModifier>(modifier))
+ op = kIROp_TrianglePrimitiveTypeDecoration;
+ else if (as<HLSLPointModifier>(modifier))
+ op = kIROp_PointPrimitiveTypeDecoration;
+ else if (as<HLSLLineModifier>(modifier))
+ op = kIROp_LinePrimitiveTypeDecoration;
+ else if (as<HLSLLineAdjModifier>(modifier))
+ op = kIROp_LineAdjPrimitiveTypeDecoration;
+ else if (as<HLSLTriangleAdjModifier>(modifier))
+ op = kIROp_TriangleAdjPrimitiveTypeDecoration;
+
+ if (op != kIROp_Invalid)
+ {
+ builder->addDecoration(irParam, op);
+ }
+ else
+ {
+ SLANG_UNEXPECTED("unhandled primitive type");
+ }
+ }
+
+ irParam = irParam->getNextParam();
+ }
+ }
+ }
}
static void lowerProgramEntryPointToIR(
diff --git a/tests/ir/string-literal.slang.expected b/tests/ir/string-literal.slang.expected
index 44bafd86a..72baa8f7e 100644
--- a/tests/ir/string-literal.slang.expected
+++ b/tests/ir/string-literal.slang.expected
@@ -1,6 +1,6 @@
result code = 0
standard error = {
-[entryPoint]
+[entryPoint(6)]
[numThreads(1, 1, 1)]
[export("_S3tu04mainp1puV")]
[nameHint("main")]