Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge from shader-slang/slang master #7

Merged
merged 3 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@
<ClCompile Include="..\..\..\tools\gfx-unit-test\gfx-test-texture-util.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\gfx-test-util.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\instanced-draw-tests.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\link-time-constant.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\mutable-shader-object.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\nested-parameter-block.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\ray-tracing-tests.cpp" />
Expand All @@ -323,6 +324,7 @@
<None Include="..\..\..\tools\gfx-unit-test\compute-trivial.slang" />
<None Include="..\..\..\tools\gfx-unit-test\format-test-shaders.slang" />
<None Include="..\..\..\tools\gfx-unit-test\graphics-smoke.slang" />
<None Include="..\..\..\tools\gfx-unit-test\link-time-constant.slang" />
<None Include="..\..\..\tools\gfx-unit-test\mutable-shader-object.slang" />
<None Include="..\..\..\tools\gfx-unit-test\nested-parameter-block.slang" />
<None Include="..\..\..\tools\gfx-unit-test\ray-tracing-test-shaders.slang" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
<ClCompile Include="..\..\..\tools\gfx-unit-test\instanced-draw-tests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tools\gfx-unit-test\link-time-constant.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tools\gfx-unit-test\mutable-shader-object.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down Expand Up @@ -121,6 +124,9 @@
<None Include="..\..\..\tools\gfx-unit-test\graphics-smoke.slang">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\..\tools\gfx-unit-test\link-time-constant.slang">
<Filter>Source Files</Filter>
</None>
<None Include="..\..\..\tools\gfx-unit-test\mutable-shader-object.slang">
<Filter>Source Files</Filter>
</None>
Expand Down
4 changes: 4 additions & 0 deletions source/slang/slang-ast-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ ArrayExpressionType* ASTBuilder::getArrayType(Type* elementType, IntVal* element
{
elementCount = getIntVal(getIntType(), elementCountConstantInt->getValue());
}
else
{
elementCount = getTypeCastIntVal(getIntType(), elementCount);
}
}
Val* args[] = {elementType, elementCount};
return as<ArrayExpressionType>(getSpecializedBuiltinType(makeArrayView(args), "ArrayExpressionType"));
Expand Down
7 changes: 6 additions & 1 deletion source/slang/slang-check-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1471,6 +1471,11 @@ namespace Slang
}
else
{
if (varDecl->hasModifier<ExternModifier>())
{
getSink()->diagnose(initExpr, Diagnostics::externValueCannotHaveInitializer);
}

initExpr = CheckExpr(initExpr);

// TODO: We might need some additional steps here to ensure
Expand All @@ -1484,7 +1489,7 @@ namespace Slang

_validateCircularVarDefinition(varDecl);
}

// If we've gone down this path, then the variable
// declaration is actually pretty far along in checking
varDecl->setCheckState(DeclCheckState::DefinitionChecked);
Expand Down
3 changes: 3 additions & 0 deletions source/slang/slang-check-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,9 @@ namespace Slang
return nullptr;
if(!decl->hasModifier<ConstModifier>())
return nullptr;
// Extern static const is not considered compile-time constant by the front-end.
if (decl->hasModifier<ExternModifier>())
return nullptr;

if (isInterfaceRequirement(decl))
{
Expand Down
8 changes: 4 additions & 4 deletions source/slang/slang-diagnostic-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,10 @@ DIAGNOSTIC(30502, Error, cannotUseInitializerListForVectorOfUnknownSize, "cannot
DIAGNOSTIC(30503, Error, cannotUseInitializerListForMatrixOfUnknownSize, "cannot use initializer list for matrix of statically unknown size '$0' rows")
DIAGNOSTIC(30504, Error, cannotUseInitializerListForType, "cannot use initializer list for type '$0'")

// 306xx: variables
DIAGNOSTIC(30600, Error, varWithoutTypeMustHaveInitializer, "a variable declaration without an initial-value expression must be given an explicit type")

DIAGNOSTIC(30610, Error, ambiguousDefaultInitializerForType, "more than one default initializer was found for type '$0'")
// 3062x: variables
DIAGNOSTIC(30620, Error, varWithoutTypeMustHaveInitializer, "a variable declaration without an initial-value expression must be given an explicit type")
DIAGNOSTIC(30621, Error, externValueCannotHaveInitializer, "an 'extern' variable declaration cannot have a value.")
DIAGNOSTIC(30622, Error, ambiguousDefaultInitializerForType, "more than one default initializer was found for type '$0'")

// 307xx: parameters
DIAGNOSTIC(30700, Error, outputParameterCannotHaveDefaultValue, "an 'out' or 'inout' parameter cannot have a default-value expression")
Expand Down
57 changes: 34 additions & 23 deletions source/slang/slang-ir-specialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1323,13 +1323,24 @@ struct SpecializationContext
// their replacements.
//
IRCloneEnv cloneEnv;
cloneEnv.squashChildrenMapping = true;

// We also need some IR building state, for any
// new instructions we will emit.
//
IRBuilder builderStorage(module);
auto builder = &builderStorage;

// To get started, we will create the skeleton of the new
// specialized function, so newly created insts
// will be placed in a proper parent.
//

IRFunc* newFunc = builder->createFunc();

builder->setInsertInto(newFunc);
IRBlock* tempHeaderBlock = builder->emitBlock();

// We will start out by determining what the parameters
// of the specialized function should be, based on
// the parameters of the original, and the concrete
Expand All @@ -1343,7 +1354,6 @@ struct SpecializationContext
// block, or even a function, to insert them into.
//
List<IRParam*> newParams;
List<IRInst*> newBodyInsts;
UInt argCounter = 0;
for (auto oldParam : oldFunc->getParams())
{
Expand Down Expand Up @@ -1387,7 +1397,6 @@ struct SpecializationContext
// correct existential type, and stores the right witness table).
//
auto newMakeExistential = builder->emitMakeExistential(oldParam->getFullType(), newParam, witnessTable);
newBodyInsts.add(newMakeExistential);
replacementVal = newMakeExistential;
}
else if (auto oldWrapExistential = as<IRWrapExistential>(arg))
Expand All @@ -1412,7 +1421,6 @@ struct SpecializationContext
newParam,
oldWrapExistential->getSlotOperandCount(),
oldWrapExistential->getSlotOperands());
newBodyInsts.add(newWrapExistential);
replacementVal = newWrapExistential;
}
else
Expand All @@ -1433,8 +1441,20 @@ struct SpecializationContext
cloneEnv.mapOldValToNew.add(oldParam, replacementVal);
}

// Next we will create the skeleton of the new
// specialized function, including its type.
// The above steps have accomplished the "first phase"
// of cloning the function (since `IRFunc`s have no
// operands).
//
// We can now use the shared IR cloning infrastructure
// to perform the second phase of cloning, which will recursively
// clone any nested decorations, blocks, and instructions.
//
cloneInstDecorationsAndChildren(
&cloneEnv,
builder->getModule(),
oldFunc,
newFunc);

//
// In order to construct the type of the new function, we
// need to extract the types of all its parameters.
Expand All @@ -1448,24 +1468,9 @@ struct SpecializationContext
newParamTypes.getCount(),
newParamTypes.getBuffer(),
oldFunc->getResultType());
IRFunc* newFunc = builder->createFunc();
newFunc->setFullType(newFuncType);

// The above steps have accomplished the "first phase"
// of cloning the function (since `IRFunc`s have no
// operands).
//
// We can now use the shared IR cloning infrastructure
// to perform the second phase of cloning, which will recursively
// clone any nested decorations, blocks, and instructions.
//
cloneInstDecorationsAndChildren(
&cloneEnv,
builder->getModule(),
oldFunc,
newFunc);

// Now that the main body of existing isntructions have
// Now that the main body of existing instructions have
// been cloned into the new function, we can go ahead
// and insert all the parameters and body instructions
// we built up into the function at the right place.
Expand All @@ -1474,7 +1479,7 @@ struct SpecializationContext
// block (this was an invariant established before
// we decided to specialize).
//
auto newEntryBlock = newFunc->getFirstBlock();
auto newEntryBlock = as<IRBlock>(cloneEnv.mapOldValToNew[oldFunc->getFirstBlock()]);
SLANG_ASSERT(newEntryBlock);

// We expect every valid block to have at least one
Expand All @@ -1497,11 +1502,17 @@ struct SpecializationContext
// before the first ordinary instruction (but will come
// *after* the parameters by the order of these two loops).
//
for (auto newBodyInst : newBodyInsts)
for (auto newBodyInst = tempHeaderBlock->getFirstChild(); newBodyInst;)
{
auto next = newBodyInst->next;
newBodyInst->insertBefore(newFirstOrdinary);
newBodyInst = next;
}

// After moving all param and existential insts in tempHeaderBlock
// it should be empty now and we can remove it.
tempHeaderBlock->removeAndDeallocate();

// After all this work we have a valid `newFunc` that has been
// specialized to match the types at the call site.
//
Expand Down
3 changes: 1 addition & 2 deletions source/slang/slang-ir-spirv-legalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
}

for (auto i : instsToRemove)
if (!i->hasUses())
i->removeAndDeallocate();
i->removeAndDeallocate();
}

// Returns true if the given type that should be decorated as in `UniformConstant` address space.
Expand Down
42 changes: 31 additions & 11 deletions source/slang/slang-mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ namespace Slang

void emitQualifiedName(
ManglingContext* context,
DeclRef<Decl> declRef);
DeclRef<Decl> declRef,
bool includeModuleName);

void emitSimpleIntVal(
ManglingContext* context,
Expand Down Expand Up @@ -211,7 +212,7 @@ namespace Slang
}
else if( auto declRefType = dynamicCast<DeclRefType>(type) )
{
emitQualifiedName(context, declRefType->getDeclRef());
emitQualifiedName(context, declRefType->getDeclRef(), true);
}
else if (auto arrType = dynamicCast<ArrayExpressionType>(type))
{
Expand All @@ -222,7 +223,7 @@ namespace Slang
else if( auto thisType = dynamicCast<ThisType>(type) )
{
emitRaw(context, "t");
emitQualifiedName(context, thisType->getInterfaceDeclRef());
emitQualifiedName(context, thisType->getInterfaceDeclRef(), true);
}
else if (const auto errorType = dynamicCast<ErrorType>(type))
{
Expand Down Expand Up @@ -356,16 +357,34 @@ namespace Slang

void emitQualifiedName(
ManglingContext* context,
DeclRef<Decl> declRef)
DeclRef<Decl> declRef,
bool includeModuleName)
{
if (!includeModuleName)
{
if (as<ModuleDecl>(declRef))
return;
}
else
{
for (auto modifier : declRef.getDecl()->modifiers)
{
if (as<ExternModifier>(modifier) || as<HLSLExportModifier>(modifier))
{
includeModuleName = false;
break;
}
}
}

auto parentDeclRef = declRef.getParent();
if (as<FileDecl>(parentDeclRef))
parentDeclRef = parentDeclRef.getParent();

auto parentGenericDeclRef = parentDeclRef.as<GenericDecl>();
if( parentDeclRef )
{
emitQualifiedName(context, parentDeclRef);
emitQualifiedName(context, parentDeclRef, includeModuleName);
}

// A generic declaration is kind of a pseudo-declaration
Expand Down Expand Up @@ -490,7 +509,7 @@ namespace Slang
for (auto type : constraint.value)
{
emitRaw(context, "C");
emitQualifiedName(context, makeDeclRef(constraint.key));
emitQualifiedName(context, makeDeclRef(constraint.key), true);
emitType(context, type);
}
}
Expand Down Expand Up @@ -579,7 +598,7 @@ namespace Slang

auto innerDecl = getInner(genericDecl);

emitQualifiedName(context, makeDeclRef(innerDecl));
emitQualifiedName(context, makeDeclRef(innerDecl), true);
return;
}
else if (as<ForwardDerivativeRequirementDecl>(decl))
Expand All @@ -592,7 +611,8 @@ namespace Slang
}

// Now we encode the qualified name of the decl.
emitQualifiedName(context, declRef);

emitQualifiedName(context, declRef, true);
}

static String getMangledName(ASTBuilder* astBuilder, DeclRef<Decl> const& declRef)
Expand Down Expand Up @@ -625,8 +645,8 @@ namespace Slang
SLANG_AST_BUILDER_RAII(astBuilder);
ManglingContext context(astBuilder);
emitRaw(&context, "_SW");
emitQualifiedName(&context, sub);
emitQualifiedName(&context, sup);
emitQualifiedName(&context, sub, true);
emitQualifiedName(&context, sup, true);
return context.sb.produceString();
}

Expand All @@ -643,7 +663,7 @@ namespace Slang
//
ManglingContext context(astBuilder);
emitRaw(&context, "_SW");
emitQualifiedName(&context, sub);
emitQualifiedName(&context, sub, true);
emitType(&context, sup);
return context.sb.produceString();
}
Expand Down
42 changes: 42 additions & 0 deletions tests/language-feature/generics/generic-interface-2.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -shaderobj -output-using-type
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -vk -shaderobj -output-using-type

interface IFoo<let n: uint>
{
static int sum(int arr[n]);
}

struct MyType<let n:uint> : IFoo<n>
{
static int sum(int arr[n])
{
int rs = 0;
for (int i = 0; i < n; i++)
rs += arr[i];
return rs;
}
}

int test<let n:uint>(IFoo<n> foo)
{
int arr[n];
for (int i =0; i < n; i++)
arr[i] = i;
return foo.sum(arr);
}

//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
RWStructuredBuffer<int> outputBuffer;

[numthreads(1, 1, 1)]
void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
{
MyType<3> t;
test(t);
// CHECK: 3
outputBuffer[0] = test(t);

int arr[3] = {1,2,3};
// CHECK: 3
outputBuffer[1] = MyType<3>.sum(arr);
}
12 changes: 12 additions & 0 deletions tests/spirv/array-of-array.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//TEST:SIMPLE(filecheck=CHECK):-target spirv -entry main -stage compute -emit-spirv-directly -skip-spirv-validation

Texture2D texArray[3][4][5];
RWStructuredBuffer<float4> outputBuffer;

// CHECK: OpEntryPoint

[shader("compute")]
void main(uint3 tid : SV_DispatchThreadID)
{
outputBuffer[0] = texArray[tid.x][tid.y][tid.z].Load(int3(1,2,3));
}
Loading
Loading