summaryrefslogtreecommitdiffstats
path: root/source/slang/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/ir.cpp')
-rw-r--r--source/slang/ir.cpp180
1 files changed, 95 insertions, 85 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index b8892cc02..0d93957c8 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -1966,6 +1966,18 @@ namespace Slang
return globalConstant;
}
+ IRGlobalParam* IRBuilder::createGlobalParam(
+ IRType* valueType)
+ {
+ IRGlobalParam* inst = createInst<IRGlobalParam>(
+ this,
+ kIROp_GlobalParam,
+ valueType);
+ maybeSetSourceLoc(this, inst);
+ addGlobalValue(this, inst);
+ return inst;
+ }
+
IRWitnessTable* IRBuilder::createWitnessTable()
{
IRWitnessTable* witnessTable = createInst<IRWitnessTable>(
@@ -3730,6 +3742,7 @@ namespace Slang
case kIROp_Generic:
case kIROp_GlobalVar:
case kIROp_GlobalConstant:
+ case kIROp_GlobalParam:
case kIROp_StructKey:
case kIROp_GlobalGenericParam:
case kIROp_WitnessTable:
@@ -3800,7 +3813,7 @@ namespace Slang
// Legalization of entry points for GLSL:
//
- IRGlobalVar* addGlobalVariable(
+ IRGlobalParam* addGlobalParam(
IRModule* module,
IRType* valueType)
{
@@ -3812,7 +3825,7 @@ namespace Slang
IRBuilder builder;
builder.sharedBuilder = &shared;
- return builder.createGlobalVar(valueType);
+ return builder.createGlobalParam(valueType);
}
void moveValueBefore(
@@ -4277,18 +4290,26 @@ namespace Slang
varLayout->stage = inVarLayout->stage;
varLayout->AddResourceInfo(kind)->index = bindingIndex;
- // Simple case: just create a global variable of the matching type,
- // and then use the value of the global as a replacement for the
- // value of the original parameter.
+ // We are going to be creating a global parameter to replace
+ // the function parameter, but we need to handle the case
+ // where the parameter represents a varying *output* and not
+ // just an input.
+ //
+ // Our IR global shader parameters are read-only, just
+ // like our IR function parameters, and need a wrapper
+ // `Out<...>` type to represent otuputs.
//
- auto globalVariable = addGlobalVariable(builder->getModule(), type);
- moveValueBefore(globalVariable, builder->getFunc());
+ bool isOutput = kind == LayoutResourceKind::VaryingOutput;
+ IRType* paramType = isOutput ? builder->getOutType(type) : type;
+
+ auto globalParam = addGlobalParam(builder->getModule(), paramType);
+ moveValueBefore(globalParam, builder->getFunc());
- ScalarizedVal val = ScalarizedVal::address(globalVariable);
+ ScalarizedVal val = isOutput ? ScalarizedVal::address(globalParam) : ScalarizedVal::value(globalParam);
if( systemValueInfo )
{
- builder->addImportDecoration(globalVariable, UnownedTerminatedStringSlice(systemValueInfo->name));
+ builder->addImportDecoration(globalParam, UnownedTerminatedStringSlice(systemValueInfo->name));
if( auto fromType = systemValueInfo->requiredType )
{
@@ -4309,11 +4330,11 @@ namespace Slang
if(auto outerArrayName = systemValueInfo->outerArrayName)
{
- builder->addGLSLOuterArrayDecoration(globalVariable, UnownedTerminatedStringSlice(outerArrayName));
+ builder->addGLSLOuterArrayDecoration(globalParam, UnownedTerminatedStringSlice(outerArrayName));
}
}
- builder->addLayoutDecoration(globalVariable, varLayout);
+ builder->addLayoutDecoration(globalParam, varLayout);
return val;
}
@@ -4865,46 +4886,22 @@ namespace Slang
auto builder = context->getBuilder();
auto paramType = pp->getDataType();
- if(auto paramPtrType = as<IROutTypeBase>(paramType) )
- {
- // This is either an `out` or `in out` parameter.
- // We want to treat `out` parameters the same
- // as `in out` for our purposes, since there are
- // no pure `out` parameters defined for the ray
- // tracing stages.
-
- // Unlike the default legalization strategy for
- // `out` and `in out` entry point parameters,
- // we will not introduce an intermediate temporary.
- //
- // Instead we will simply create a global variable
- // and replace uses of the parameter with uses
- // of that global variable.
-
- auto valueType = paramPtrType->getValueType();
-
- auto globalVariable = addGlobalVariable(builder->getModule(), valueType);
- builder->addLayoutDecoration(globalVariable, paramLayout);
- moveValueBefore(globalVariable, builder->getFunc());
-
- pp->replaceUsesWith(globalVariable);
- }
- else
- {
- // This is the `in` parameter case, so that the parameter
- // was not a pointer. We will allocate a global variable
- // to represent the parameter, and then perform a load
- // form it at the start of the function.
- //
- auto valueType = paramType;
- auto globalVariable = addGlobalVariable(builder->getModule(), valueType);
- builder->addLayoutDecoration(globalVariable, paramLayout);
- moveValueBefore(globalVariable, builder->getFunc());
-
- auto irLoad = builder->emitLoad(globalVariable);
- pp->replaceUsesWith(irLoad);
- }
-
+ // The parameter might be either an `in` parameter,
+ // or an `out` or `in out` parameter, and in those
+ // latter cases its IR-level type will include a
+ // wrapping "pointer-like" type (e.g., `Out<Float>`
+ // instead of just `Float`).
+ //
+ // Because global shader parameters are read-only
+ // in the same way function types are, we can take
+ // care of that detail here just by allocating a
+ // global shader parameter with exactly the type
+ // of the original function parameter.
+ //
+ auto globalParam = addGlobalParam(builder->getModule(), paramType);
+ builder->addLayoutDecoration(globalParam, paramLayout);
+ moveValueBefore(globalParam, builder->getFunc());
+ pp->replaceUsesWith(globalParam);
}
void legalizeEntryPointParameterForGLSL(
@@ -5629,6 +5626,7 @@ namespace Slang
case kIROp_Generic:
case kIROp_GlobalVar:
case kIROp_GlobalConstant:
+ case kIROp_GlobalParam:
case kIROp_StructKey:
case kIROp_GlobalGenericParam:
case kIROp_WitnessTable:
@@ -5779,21 +5777,6 @@ namespace Slang
registerClonedValue(context, clonedVar, originalValues);
-#if 0
- auto mangledName = originalVar->mangledName;
- clonedVar->mangledName = mangledName;
-#endif
-
- if(auto linkage = originalVar->findDecoration<IRLinkageDecoration>())
- {
- auto mangledName = String(linkage->getMangledName());
- VarLayout* layout = nullptr;
- if (context->globalVarLayouts.TryGetValue(mangledName, layout))
- {
- builder->addLayoutDecoration(clonedVar, layout);
- }
- }
-
// Clone any code in the body of the variable, since this
// represents the initializer.
cloneGlobalValueWithCodeCommon(
@@ -5824,25 +5807,6 @@ namespace Slang
return clonedVal;
}
- IRGeneric* cloneGenericImpl(
- IRSpecContextBase* context,
- IRBuilder* builder,
- IRGeneric* originalVal,
- IROriginalValuesForClone const& originalValues)
- {
- auto clonedVal = builder->emitGeneric();
- registerClonedValue(context, clonedVal, originalValues);
-
- // Clone any code in the body of the generic, since this
- // computes its result value.
- cloneGlobalValueWithCodeCommon(
- context,
- clonedVal,
- originalVal);
-
- return clonedVal;
- }
-
void cloneSimpleGlobalValueImpl(
IRSpecContextBase* context,
IRInst* originalInst,
@@ -5865,6 +5829,48 @@ namespace Slang
}
}
+ IRGlobalParam* cloneGlobalParamImpl(
+ IRSpecContextBase* context,
+ IRBuilder* builder,
+ IRGlobalParam* originalVal,
+ IROriginalValuesForClone const& originalValues)
+ {
+ auto clonedVal = builder->createGlobalParam(
+ cloneType(context, originalVal->getFullType()));
+ cloneSimpleGlobalValueImpl(context, originalVal, originalValues, clonedVal);
+
+ if(auto linkage = originalVal->findDecoration<IRLinkageDecoration>())
+ {
+ auto mangledName = String(linkage->getMangledName());
+ VarLayout* layout = nullptr;
+ if (context->globalVarLayouts.TryGetValue(mangledName, layout))
+ {
+ builder->addLayoutDecoration(clonedVal, layout);
+ }
+ }
+
+ return clonedVal;
+ }
+
+ IRGeneric* cloneGenericImpl(
+ IRSpecContextBase* context,
+ IRBuilder* builder,
+ IRGeneric* originalVal,
+ IROriginalValuesForClone const& originalValues)
+ {
+ auto clonedVal = builder->emitGeneric();
+ registerClonedValue(context, clonedVal, originalValues);
+
+ // Clone any code in the body of the generic, since this
+ // computes its result value.
+ cloneGlobalValueWithCodeCommon(
+ context,
+ clonedVal,
+ originalVal);
+
+ return clonedVal;
+ }
+
IRStructKey* cloneStructKeyImpl(
IRSpecContextBase* context,
IRBuilder* builder,
@@ -6254,6 +6260,7 @@ namespace Slang
case kIROp_StructType:
case kIROp_GlobalVar:
+ case kIROp_GlobalParam:
return true;
default:
@@ -6350,6 +6357,9 @@ namespace Slang
case kIROp_GlobalConstant:
return cloneGlobalConstantImpl(context, builder, cast<IRGlobalConstant>(originalInst), originalValues);
+ case kIROp_GlobalParam:
+ return cloneGlobalParamImpl(context, builder, cast<IRGlobalParam>(originalInst), originalValues);
+
case kIROp_WitnessTable:
return cloneWitnessTableImpl(context, builder, cast<IRWitnessTable>(originalInst), originalValues);