Skip to content

Commit 0a3e2dc

Browse files
authored
Merge branch 'master' into shader-object-refactor
2 parents 03d2f53 + cd20e94 commit 0a3e2dc

File tree

67 files changed

+1443
-326
lines changed

Some content is hidden

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

67 files changed

+1443
-326
lines changed

.github/workflows/ci.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ jobs:
166166
-use-test-server \
167167
-category ${{ matrix.test-category }} \
168168
-api all-dx12 \
169-
-expected-failure-list tests/expected-failure-github.txt
169+
-expected-failure-list tests/expected-failure-github.txt \
170+
-expected-failure-list tests/expected-failure-record-replay-tests.txt
170171
else
171172
"$bin_dir/slang-test" \
172173
-use-test-server \
@@ -176,7 +177,7 @@ jobs:
176177
-expected-failure-list tests/expected-failure-record-replay-tests.txt
177178
fi
178179
- name: Run Slang examples
179-
if: steps.filter.outputs.should-run == 'true' && matrix.platform != 'wasm'
180+
if: steps.filter.outputs.should-run == 'true' && matrix.platform != 'wasm' && matrix.full-gpu-tests
180181
run: |
181182
.github/workflows/ci-examples.sh \
182183
--bin-dir "$bin_dir" \

docs/user-guide/08-compiling.md

+4
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,10 @@ for compiling GLSL code. Without this setting, compiling GLSL code will result i
603603
> Currently, the global session type is *not* thread-safe.
604604
> Applications that wish to compile on multiple threads will need to ensure that each concurrent thread compiles with a distinct global session.
605605
606+
> #### Note ####
607+
> Currently, the global session should be freed after any objects created from it.
608+
> See [issue 6344](https://github.com/shader-slang/slang/issues/6344).
609+
606610
### Creating a Session
607611
608612
A _session_ uses the interface `slang::ISession`, and represents a scope for compilation with a consistent set of compiler options.

source/slang/glsl.meta.slang

+21-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,27 @@ public property uint3 gl_WorkGroupSize
136136
// TODO: define overload for tessellation control stage.
137137
public in int gl_InvocationID : SV_GSInstanceID;
138138

139-
public in int gl_InstanceIndex : SV_InstanceID;
139+
internal in int __sv_InstanceIndex : SV_InstanceID;
140+
141+
// SPIRV InstanceIndex builtin for vertex shader
142+
public property int gl_InstanceIndex
143+
{
144+
[require(vertex)]
145+
get
146+
{
147+
__target_switch
148+
{
149+
default:
150+
return __sv_InstanceIndex;
151+
case glsl:
152+
__intrinsic_asm "gl_InstanceIndex";
153+
case spirv:
154+
return spirv_asm {
155+
result:$$int = OpLoad builtin(InstanceIndex:int);
156+
};
157+
}
158+
}
159+
}
140160
public in bool gl_FrontFacing : SV_IsFrontFace;
141161

142162
// TODO: define overload for geometry stage.

source/slang/slang-artifact-output-util.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "../core/slang-string-util.h"
77
#include "../core/slang-type-text-util.h"
88

9+
#include <chrono>
10+
911
// Artifact
1012
#include "../compiler-core/slang-artifact-desc-util.h"
1113
#include "../compiler-core/slang-artifact-util.h"

source/slang/slang-ast-base.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -741,9 +741,9 @@ class ModifiableSyntaxNode : public SyntaxNode
741741
}
742742
};
743743

744-
struct DeclReferenceWithLoc
744+
struct ProvenenceNodeWithLoc
745745
{
746-
Decl* referencedDecl;
746+
NodeBase* referencedNode;
747747
SourceLoc referenceLoc;
748748
};
749749

@@ -789,7 +789,7 @@ class Decl : public DeclBase
789789
bool isChildOf(Decl* other) const;
790790

791791
// Track the decl reference that caused the requirement of a capability atom.
792-
SLANG_UNREFLECTED List<DeclReferenceWithLoc> capabilityRequirementProvenance;
792+
SLANG_UNREFLECTED List<ProvenenceNodeWithLoc> capabilityRequirementProvenance;
793793

794794
SLANG_UNREFLECTED bool hiddenFromLookup = false;
795795

source/slang/slang-check-decl.cpp

+111-56
Original file line numberDiff line numberDiff line change
@@ -12744,11 +12744,11 @@ static void _propagateRequirement(
1274412744
// if stmt inside parent, set the provenance tracker to the calling function
1274512745
if (!decl)
1274612746
decl = visitor->getParentFuncOfVisitor();
12747-
if (referencedDecl && decl)
12747+
if (referencedNode && decl)
1274812748
{
1274912749
// Here we store a childDecl that added/removed capabilities from a parentDecl
1275012750
decl->capabilityRequirementProvenance.add(
12751-
DeclReferenceWithLoc{referencedDecl, referenceLoc});
12751+
ProvenenceNodeWithLoc{referencedNode, referenceLoc});
1275212752
}
1275312753
};
1275412754

@@ -12977,15 +12977,19 @@ CapabilitySet SemanticsDeclCapabilityVisitor::getDeclaredCapabilitySet(Decl* dec
1297712977
// The requirement for `foo` should be glsl+glsl_ext_1 | spirv.
1297812978
//
1297912979
CapabilitySet declaredCaps;
12980+
CapabilityAtom stageToJoin = CapabilityAtom::Invalid;
1298012981
for (Decl* parent = decl; parent; parent = getParentDecl(parent))
1298112982
{
1298212983
CapabilitySet localDeclaredCaps;
1298312984
bool shouldBreak = false;
1298412985
if (!as<AggTypeDeclBase>(parent) || parent->inferredCapabilityRequirements.isEmpty())
1298512986
{
12986-
for (auto decoration : parent->getModifiersOfType<RequireCapabilityAttribute>())
12987+
for (auto mod : parent->modifiers)
1298712988
{
12988-
localDeclaredCaps.unionWith(decoration->capabilitySet);
12989+
if (auto decoration = as<RequireCapabilityAttribute>(mod))
12990+
localDeclaredCaps.unionWith(decoration->capabilitySet);
12991+
else if (auto entrypoint = as<EntryPointAttribute>(mod))
12992+
stageToJoin = entrypoint->capabilitySet.getTargetStage();
1298912993
}
1299012994
}
1299112995
else
@@ -13001,6 +13005,8 @@ CapabilitySet SemanticsDeclCapabilityVisitor::getDeclaredCapabilitySet(Decl* dec
1300113005
if (shouldBreak)
1300213006
break;
1300313007
}
13008+
if (!declaredCaps.isEmpty() && stageToJoin != CapabilityAtom::Invalid)
13009+
declaredCaps.join(CapabilitySet((CapabilityName)stageToJoin));
1300413010
return declaredCaps;
1300513011
}
1300613012

@@ -13298,63 +13304,83 @@ void diagnoseMissingCapabilityProvenance(
1329813304
Decl* decl,
1329913305
CapabilitySet& setToFind)
1330013306
{
13301-
HashSet<Decl*> checkedDecls;
13302-
DeclReferenceWithLoc declWithRef;
13303-
declWithRef.referencedDecl = decl;
13304-
declWithRef.referenceLoc = (decl) ? decl->loc : SourceLoc();
13307+
HashSet<NodeBase*> checkedDecls;
13308+
ProvenenceNodeWithLoc provNode;
13309+
provNode.referencedNode = decl;
13310+
provNode.referenceLoc = (decl) ? decl->loc : SourceLoc();
1330513311
bool bottomOfProvenanceStack = false;
1330613312
// Find the bottom of the atom provenance stack which fails to contain `setToFind`
13307-
while (!bottomOfProvenanceStack && declWithRef.referencedDecl)
13313+
while (!bottomOfProvenanceStack && provNode.referencedNode)
1330813314
{
1330913315
bottomOfProvenanceStack = true;
13310-
for (auto& i : declWithRef.referencedDecl->capabilityRequirementProvenance)
13316+
if (auto referencedDecl = as<Decl>(provNode.referencedNode))
1331113317
{
13312-
if (checkedDecls.contains(i.referencedDecl))
13313-
continue;
13314-
checkedDecls.add(i.referencedDecl);
13315-
13316-
if (!i.referencedDecl->inferredCapabilityRequirements.implies(setToFind))
13318+
for (auto& i : referencedDecl->capabilityRequirementProvenance)
1331713319
{
13318-
// We found a source of the incompatible capability, follow this
13319-
// element inside the provenance stack until we are at the bottom
13320-
declWithRef = i;
13321-
bottomOfProvenanceStack = false;
13322-
break;
13320+
if (checkedDecls.contains(i.referencedNode))
13321+
continue;
13322+
checkedDecls.add(i.referencedNode);
13323+
auto innerReferencedDecl = as<Decl>(i.referencedNode);
13324+
if (!innerReferencedDecl ||
13325+
!innerReferencedDecl->inferredCapabilityRequirements.implies(setToFind))
13326+
{
13327+
// We found a source of the incompatible capability, follow this
13328+
// element inside the provenance stack until we are at the bottom
13329+
provNode = i;
13330+
bottomOfProvenanceStack = false;
13331+
break;
13332+
}
1332313333
}
1332413334
}
13335+
else
13336+
{
13337+
bottomOfProvenanceStack = true;
13338+
}
1332513339
}
1332613340

13327-
if (!declWithRef.referencedDecl)
13341+
if (!provNode.referencedNode)
1332813342
return;
1332913343

13330-
// Diagnose the use-site
13331-
maybeDiagnose(
13332-
sink,
13333-
optionSet,
13334-
DiagnosticCategory::Capability,
13335-
declWithRef.referenceLoc,
13336-
Diagnostics::seeUsingOf,
13337-
declWithRef.referencedDecl);
13338-
// Diagnose the definition as the problem
13339-
maybeDiagnose(
13340-
sink,
13341-
optionSet,
13342-
DiagnosticCategory::Capability,
13343-
declWithRef.referencedDecl->loc,
13344-
Diagnostics::seeDefinitionOf,
13345-
declWithRef.referencedDecl);
13346-
13347-
// If we find a 'require' modifier, this is contributing to the overall capability
13348-
// incompatibility. We should hint to the user that this declaration is problematic.
13349-
if (auto requireCapabilityAttribute =
13350-
declWithRef.referencedDecl->findModifier<RequireCapabilityAttribute>())
13344+
if (auto referencedDecl = as<Decl>(provNode.referencedNode))
13345+
{
13346+
// Diagnose the use-site
1335113347
maybeDiagnose(
1335213348
sink,
1335313349
optionSet,
1335413350
DiagnosticCategory::Capability,
13355-
requireCapabilityAttribute->loc,
13356-
Diagnostics::seeDeclarationOf,
13357-
requireCapabilityAttribute);
13351+
provNode.referenceLoc,
13352+
Diagnostics::seeUsingOf,
13353+
referencedDecl);
13354+
// Diagnose the definition as the problem
13355+
maybeDiagnose(
13356+
sink,
13357+
optionSet,
13358+
DiagnosticCategory::Capability,
13359+
referencedDecl->loc,
13360+
Diagnostics::seeDefinitionOf,
13361+
referencedDecl);
13362+
// If we find a 'require' modifier, this is contributing to the overall capability
13363+
// incompatibility. We should hint to the user that this declaration is problematic.
13364+
if (auto requireCapabilityAttribute =
13365+
referencedDecl->findModifier<RequireCapabilityAttribute>())
13366+
maybeDiagnose(
13367+
sink,
13368+
optionSet,
13369+
DiagnosticCategory::Capability,
13370+
requireCapabilityAttribute->loc,
13371+
Diagnostics::seeDeclarationOf,
13372+
requireCapabilityAttribute);
13373+
}
13374+
else
13375+
{
13376+
maybeDiagnose(
13377+
sink,
13378+
optionSet,
13379+
DiagnosticCategory::Capability,
13380+
provNode.referenceLoc,
13381+
Diagnostics::seeUsingOf,
13382+
provNode.referencedNode->astNodeType);
13383+
}
1335813384
}
1335913385

1336013386
void diagnoseCapabilityProvenance(
@@ -13372,16 +13398,29 @@ void diagnoseCapabilityProvenance(
1337213398
printedDecls.add(declToPrint);
1337313399
for (auto& provenance : declToPrint->capabilityRequirementProvenance)
1337413400
{
13375-
if (!provenance.referencedDecl->inferredCapabilityRequirements.implies(atomToFind))
13401+
auto referencedDecl = as<Decl>(provenance.referencedNode);
13402+
if (!referencedDecl)
13403+
{
13404+
maybeDiagnose(
13405+
sink,
13406+
optionSet,
13407+
DiagnosticCategory::Capability,
13408+
provenance.referenceLoc,
13409+
Diagnostics::seeUsingOf,
13410+
provenance.referencedNode->astNodeType);
13411+
break;
13412+
}
13413+
13414+
if (!referencedDecl->inferredCapabilityRequirements.implies(atomToFind))
1337613415
continue;
1337713416
maybeDiagnose(
1337813417
sink,
1337913418
optionSet,
1338013419
DiagnosticCategory::Capability,
1338113420
provenance.referenceLoc,
1338213421
Diagnostics::seeUsingOf,
13383-
provenance.referencedDecl);
13384-
declToPrint = provenance.referencedDecl;
13422+
referencedDecl);
13423+
declToPrint = referencedDecl;
1338513424
if (printedDecls.contains(declToPrint))
1338613425
break;
1338713426
if (declToPrint->findModifier<RequireCapabilityAttribute>())
@@ -13487,14 +13526,30 @@ void SemanticsDeclCapabilityVisitor::diagnoseUndeclaredCapability(
1348713526
for (auto i : simplifiedFailedAtomsSet)
1348813527
{
1348913528
CapabilityAtom formattedAtom = asAtom(i);
13490-
maybeDiagnose(
13491-
getSink(),
13492-
this->getOptionSet(),
13493-
DiagnosticCategory::Capability,
13494-
decl->loc,
13495-
diagnosticInfo,
13496-
decl,
13497-
formattedAtom);
13529+
CapabilityName canonicalName;
13530+
if (isStageAtom((CapabilityName)formattedAtom, canonicalName))
13531+
{
13532+
// Provide a more friendly message if atom is a stage.
13533+
maybeDiagnose(
13534+
getSink(),
13535+
this->getOptionSet(),
13536+
DiagnosticCategory::Capability,
13537+
decl->loc,
13538+
Diagnostics::declHasDependenciesNotCompatibleOnStage,
13539+
decl,
13540+
formattedAtom);
13541+
}
13542+
else
13543+
{
13544+
maybeDiagnose(
13545+
getSink(),
13546+
this->getOptionSet(),
13547+
DiagnosticCategory::Capability,
13548+
decl->loc,
13549+
diagnosticInfo,
13550+
decl,
13551+
formattedAtom);
13552+
}
1349813553
// Print provenances.
1349913554
diagnoseCapabilityProvenance(
1350013555
this->getOptionSet(),

0 commit comments

Comments
 (0)