summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-05-02 20:29:38 -0700
committerGitHub <noreply@github.com>2023-05-02 20:29:38 -0700
commitd52376a65f37fcbbb67428b917fd3819436b6dfb (patch)
treeda25b3c9a00bd003b1970b4a6c4eb38eccf62aa1
parent55291b0bf6d729fcbaf75a01926da7da8975b8e9 (diff)
Various dxc/fxc compatibility fixes. (#2863)
* Various dxc/fxc compatibility fixes. * Cleanup. * Fix test cases. * Fix comments. --------- Co-authored-by: Yong He <yhe@nvidia.com>
-rw-r--r--build/visual-studio/slang/slang.vcxproj2
-rw-r--r--build/visual-studio/slang/slang.vcxproj.filters6
-rw-r--r--slang.h5
-rw-r--r--source/slang/core.meta.slang14
-rw-r--r--source/slang/slang-api.cpp1
-rw-r--r--source/slang/slang-ast-modifier.h14
-rw-r--r--source/slang/slang-check-modifier.cpp34
-rwxr-xr-xsource/slang/slang-compiler.h12
-rw-r--r--source/slang/slang-diagnostic-defs.h4
-rw-r--r--source/slang/slang-emit-c-like.cpp69
-rw-r--r--source/slang/slang-emit-c-like.h11
-rw-r--r--source/slang/slang-emit-cuda.cpp4
-rw-r--r--source/slang/slang-emit-cuda.h2
-rw-r--r--source/slang/slang-emit-glsl.cpp40
-rw-r--r--source/slang/slang-emit-glsl.h2
-rw-r--r--source/slang/slang-emit-hlsl.cpp49
-rw-r--r--source/slang/slang-emit-hlsl.h4
-rw-r--r--source/slang/slang-emit.cpp6
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--source/slang/slang-ir-insts.h12
-rw-r--r--source/slang/slang-ir-legalize-uniform-buffer-load.cpp50
-rw-r--r--source/slang/slang-ir-legalize-uniform-buffer-load.h12
-rw-r--r--source/slang/slang-ir-use-uninitialized-out-param.cpp1
-rw-r--r--source/slang/slang-ir-util.cpp5
-rw-r--r--source/slang/slang-lower-to-ir.cpp35
-rw-r--r--source/slang/slang-options.cpp25
-rw-r--r--source/slang/slang-parameter-binding.cpp6
-rw-r--r--source/slang/slang-parser.cpp65
-rw-r--r--source/slang/slang-type-layout.cpp50
-rw-r--r--source/slang/slang-type-layout.h4
-rw-r--r--source/slang/slang.cpp11
-rw-r--r--tests/bindings/glsl-parameter-blocks.slang.glsl25
-rw-r--r--tests/bugs/gh-941.slang.glsl7
-rw-r--r--tests/cross-compile/array-of-buffers.slang.glsl12
-rw-r--r--tests/cross-compile/glsl-empty-struct-param-field.slang.glsl4
-rw-r--r--tests/cross-compile/half-conversion.slang.glsl4
-rw-r--r--tests/cross-compile/texture-load.slang.glsl6
-rw-r--r--tests/cross-compile/unknown-image-format.slang.glsl14
-rw-r--r--tests/cross-compile/vector-comparison.slang.glsl5
-rw-r--r--tests/cross-compile/vk-push-constant-set.slang.glsl6
-rw-r--r--tests/diagnostics/packoffset.slang11
-rw-r--r--tests/diagnostics/packoffset.slang.expected8
-rw-r--r--tests/diagnostics/register-bindings.slang2
-rw-r--r--tests/diagnostics/register-bindings.slang.expected3
-rw-r--r--tests/hlsl/packoffset.slang33
-rw-r--r--tests/hlsl/packoffset.slang.expected.txt5
-rw-r--r--tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl130
-rw-r--r--tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl137
-rw-r--r--tests/vkray/anyhit.slang.glsl4
-rw-r--r--tests/vkray/callable-caller.slang.glsl4
-rw-r--r--tests/vkray/closesthit.slang.glsl4
-rw-r--r--tests/vkray/entry-point-params.slang.glsl4
-rw-r--r--tests/vkray/intersection.slang.glsl4
-rw-r--r--tests/vkray/raygen.slang.glsl9
54 files changed, 838 insertions, 160 deletions
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj
index 5307b4c2a..7e0348d73 100644
--- a/build/visual-studio/slang/slang.vcxproj
+++ b/build/visual-studio/slang/slang.vcxproj
@@ -395,6 +395,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-ir-layout.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-legalize-array-return-type.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-legalize-mesh-outputs.h" />
+ <ClInclude Include="..\..\..\source\slang\slang-ir-legalize-uniform-buffer-load.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-legalize-varying-params.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-link.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-liveness.h" />
@@ -589,6 +590,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-array-return-type.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-mesh-outputs.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-types.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-ir-legalize-uniform-buffer-load.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-varying-params.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-link.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-liveness.cpp" />
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters
index eb697046e..cae2199b8 100644
--- a/build/visual-studio/slang/slang.vcxproj.filters
+++ b/build/visual-studio/slang/slang.vcxproj.filters
@@ -273,6 +273,9 @@
<ClInclude Include="..\..\..\source\slang\slang-ir-legalize-mesh-outputs.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\slang\slang-ir-legalize-uniform-buffer-load.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-legalize-varying-params.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -851,6 +854,9 @@
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-types.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-ir-legalize-uniform-buffer-load.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-varying-params.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/slang.h b/slang.h
index 89ef4ce4e..f5092a1e6 100644
--- a/slang.h
+++ b/slang.h
@@ -4122,6 +4122,9 @@ namespace slang
/** Set the debug format to be used for debugging information */
virtual SLANG_NO_THROW void SLANG_MCALL setDebugInfoFormat(SlangDebugInfoFormat debugFormat) = 0;
+
+ virtual SLANG_NO_THROW void SLANG_MCALL setEnableEffectAnnotations(bool value) = 0;
+
};
#define SLANG_UUID_ICompileRequest ICompileRequest::getTypeGuid()
@@ -4208,6 +4211,8 @@ namespace slang
SlangInt preprocessorMacroCount = 0;
ISlangFileSystem* fileSystem = nullptr;
+
+ bool enableEffectAnnotations = false;
};
enum class ContainerType
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 6a35f496b..a2ed1d1df 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -762,6 +762,8 @@ struct String
}
};
+typedef String string;
+
__magic_type(NativeStringType)
__intrinsic_type($(kIROp_NativeStringType))
struct NativeString
@@ -1334,8 +1336,8 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
}
// `GetDimensions`
-
- for(int isFloat = 0; isFloat < 2; ++isFloat)
+ const char* dimParamTypes[] = {"out float ", "out int ", "out uint "};
+ for(auto t : dimParamTypes)
for(int includeMipInfo = 0; includeMipInfo < 2; ++includeMipInfo)
{
{
@@ -1417,8 +1419,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
sb << ")\")\n";
}
- char const* t = isFloat ? "out float " : "out uint ";
-
sb << "[__readNone]\n";
sb << "void GetDimensions(";
if(includeMipInfo)
@@ -2967,6 +2967,12 @@ attribute_syntax [vk_index(index : int)] : GLSLIndexAttribute;
__attributeTarget(FuncDecl)
attribute_syntax [vk_spirv_instruction(op : int, set : String = "")] : SPIRVInstructionOpAttribute;
+__attributeTarget(FuncDecl)
+attribute_syntax [spv_target_env_1_3] : SPIRVTargetEnv13Attribute;
+
+__attributeTarget(VarDeclBase)
+attribute_syntax [disable_array_flattening] : DisableArrayFlatteningAttribute;
+
// Statement Attributes
__attributeTarget(LoopStmt)
diff --git a/source/slang/slang-api.cpp b/source/slang/slang-api.cpp
index a03aa9071..864bc8b7d 100644
--- a/source/slang/slang-api.cpp
+++ b/source/slang/slang-api.cpp
@@ -284,7 +284,6 @@ SLANG_API void spSetLineDirectiveMode(
request->setLineDirectiveMode(mode);
}
-
SLANG_API void spSetTargetForceGLSLScalarBufferLayout(
slang::ICompileRequest* request, int targetIndex, bool forceScalarLayout)
{
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 1083afae4..ab66febb9 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -304,6 +304,8 @@ class HLSLRegisterSemantic : public HLSLLayoutSemantic
class HLSLPackOffsetSemantic : public HLSLLayoutSemantic
{
SLANG_AST_CLASS(HLSLPackOffsetSemantic)
+
+ Index uniformOffset = 0;
};
@@ -731,6 +733,18 @@ class SPIRVInstructionOpAttribute : public Attribute
SLANG_AST_CLASS(SPIRVInstructionOpAttribute)
};
+// [[spv_target_env_1_3]]
+class SPIRVTargetEnv13Attribute : public Attribute
+{
+ SLANG_AST_CLASS(SPIRVTargetEnv13Attribute);
+};
+
+// [[disable_array_flattening]]
+class DisableArrayFlatteningAttribute : public Attribute
+{
+ SLANG_AST_CLASS(DisableArrayFlatteningAttribute);
+};
+
// TODO: for attributes that take arguments, the syntax node
// classes should provide accessors for the values of those arguments.
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 61f3f1196..2d5f6aad7 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -918,6 +918,40 @@ namespace Slang
// See SemanticsDeclHeaderVisitor::checkExtensionExternVarAttribute.
}
}
+
+ if (auto packOffsetModifier = as<HLSLPackOffsetSemantic>(m))
+ {
+ if (!packOffsetModifier->registerName.getContent().startsWith("c"))
+ {
+ getSink()->diagnose(packOffsetModifier, Diagnostics::unknownRegisterClass, packOffsetModifier->registerName);
+ return m;
+ }
+ auto uniformOffset = stringToInt(packOffsetModifier->registerName.getContent().tail(1)) * 16;
+ if (packOffsetModifier->componentMask.getContentLength())
+ {
+ switch (packOffsetModifier->componentMask.getContent()[0])
+ {
+ case 'x':
+ uniformOffset += 0;
+ break;
+ case 'y':
+ uniformOffset += 4;
+ break;
+ case 'z':
+ uniformOffset += 8;
+ break;
+ case 'w':
+ uniformOffset += 12;
+ break;
+ default:
+ getSink()->diagnose(packOffsetModifier, Diagnostics::invalidComponentMask, packOffsetModifier->componentMask);
+ break;
+ }
+ }
+ packOffsetModifier->uniformOffset = uniformOffset;
+ return packOffsetModifier;
+ }
+
// Default behavior is to leave things as they are,
// and assume that modifiers are mostly already checked.
//
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index fc46b25b6..117c3f037 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1589,7 +1589,6 @@ namespace Slang
SlangTargetFlags getTargetFlags() { return targetFlags; }
CapabilitySet getTargetCaps();
bool getForceGLSLScalarBufferLayout() { return forceGLSLScalarBufferLayout; }
-
Session* getSession();
MatrixLayoutMode getDefaultMatrixLayoutMode();
@@ -1756,6 +1755,15 @@ namespace Slang
/// Get the parent session for this linkage
Session* getSessionImpl() { return m_session; }
+ bool getEnableEffectAnnotations()
+ {
+ return m_enableEffectAnnotations;
+ }
+ void setEnableEffectAnnotations(bool value)
+ {
+ m_enableEffectAnnotations = value;
+ }
+
// Information on the targets we are being asked to
// generate code for.
List<RefPtr<TargetRequest>> targets;
@@ -1914,6 +1922,7 @@ namespace Slang
bool m_requireCacheFileSystem = false;
bool m_useFalcorCustomSharedKeywordSemantics = false;
+ bool m_enableEffectAnnotations = false;
// Modules that have been read in with the -r option
List<ComPtr<IArtifact>> m_libModules;
@@ -2550,6 +2559,7 @@ namespace Slang
virtual SLANG_NO_THROW SlangCompileFlags SLANG_MCALL getCompileFlags() SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setDumpIntermediates(int enable) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setDumpIntermediatePrefix(const char* prefix) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void SLANG_MCALL setEnableEffectAnnotations(bool value) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setLineDirectiveMode(SlangLineDirectiveMode mode) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setCodeGenTarget(SlangCompileTarget target) SLANG_OVERRIDE;
virtual SLANG_NO_THROW int SLANG_MCALL addCodeGenTarget(SlangCompileTarget target) SLANG_OVERRIDE;
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 0b6494ad5..a35c48a6a 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -544,8 +544,8 @@ DIAGNOSTIC(39007, Error, unknownRegisterClass, "unknown register class: '$0'")
DIAGNOSTIC(39008, Error, expectedARegisterIndex, "expected a register index after '$0'")
DIAGNOSTIC(39009, Error, expectedSpace, "expected 'space', got '$0'")
DIAGNOSTIC(39010, Error, expectedSpaceIndex, "expected a register space index after 'space'")
-DIAGNOSTIC(39011, Error, componentMaskNotSupported, "explicit register component masks are not yet supported in Slang")
-DIAGNOSTIC(39012, Error, packOffsetNotSupported, "explicit 'packoffset' bindings are not yet supported in Slang")
+DIAGNOSTIC(39011, Error, invalidComponentMask, "invalid register component mask '$0'.")
+
DIAGNOSTIC(39013, Warning, registerModifierButNoVulkanLayout, "shader parameter '$0' has a 'register' specified for D3D, but no '[[vk::binding(...)]]` specified for Vulkan")
DIAGNOSTIC(39014, Error, unexpectedSpecifierAfterSpace, "unexpected specifier after register space: '$0'")
DIAGNOSTIC(39015, Error, wholeSpaceParameterRequiresZeroBinding, "shader parameter '$0' consumes whole descriptor sets, so the binding must be in the form '[[vk::binding(0, ...)]]'; the non-zero binding '$1' is not allowed")
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 5a40b51ef..2b5323e3f 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -1797,6 +1797,37 @@ void CLikeSourceEmitter::diagnoseUnhandledInst(IRInst* inst)
getSink()->diagnose(inst, Diagnostics::unimplemented, "unexpected IR opcode during code emit");
}
+bool CLikeSourceEmitter::hasExplicitConstantBufferOffset(IRInst* cbufferType)
+{
+ auto type = as<IRUniformParameterGroupType>(cbufferType);
+ if (!type)
+ return false;
+ if (as<IRGLSLShaderStorageBufferType>(cbufferType))
+ return false;
+ auto structType = as<IRStructType>(type->getElementType());
+ if (!structType)
+ return false;
+ for (auto ff : structType->getFields())
+ {
+ if (ff->getKey()->findDecoration<IRPackOffsetDecoration>())
+ return true;
+ }
+ return false;
+}
+
+bool CLikeSourceEmitter::isSingleElementConstantBuffer(IRInst* cbufferType)
+{
+ auto type = as<IRUniformParameterGroupType>(cbufferType);
+ if (!type)
+ return false;
+ if (as<IRGLSLShaderStorageBufferType>(cbufferType))
+ return false;
+ auto structType = as<IRStructType>(type->getElementType());
+ if (structType)
+ return false;
+ return true;
+}
+
void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inOuterPrec)
{
EmitOpInfo outerPrec = inOuterPrec;
@@ -1895,11 +1926,6 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
m_writer->emit("->");
else
m_writer->emit(".");
- if(getSourceLanguage() == SourceLanguage::GLSL
- && as<IRUniformParameterGroupType>(base->getDataType()))
- {
- m_writer->emit("_data.");
- }
m_writer->emit(getName(fieldExtract->getField()));
break;
}
@@ -1930,14 +1956,13 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
{
auto prec = getInfo(EmitOp::Postfix);
needClose = maybeEmitParens(outerPrec, prec);
-
- auto base = ii->getBase();
- emitOperand(base, leftSide(outerPrec, prec));
- m_writer->emit(".");
- if(getSourceLanguage() == SourceLanguage::GLSL
- && as<IRUniformParameterGroupType>(base->getDataType()))
+ auto skipBase = isD3DTarget(getTargetReq()) &&
+ hasExplicitConstantBufferOffset(ii->getBase()->getDataType());
+ if (!skipBase)
{
- m_writer->emit("_data.");
+ auto base = ii->getBase();
+ emitOperand(base, leftSide(outerPrec, prec));
+ m_writer->emit(".");
}
m_writer->emit(getName(ii->getField()));
}
@@ -2032,8 +2057,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
{
auto base = inst->getOperand(0);
emitDereferenceOperand(base, outerPrec);
- if(getSourceLanguage() == SourceLanguage::GLSL
- && as<IRUniformParameterGroupType>(base->getDataType()))
+ if (isKhronosTarget(getTargetReq()) && isSingleElementConstantBuffer(base->getDataType()))
{
m_writer->emit("._data");
}
@@ -2628,9 +2652,9 @@ void CLikeSourceEmitter::emitSemanticsUsingVarLayout(IRVarLayout* varLayout)
}
}
-void CLikeSourceEmitter::emitSemantics(IRInst* inst)
+void CLikeSourceEmitter::emitSemantics(IRInst* inst, bool allowOffsetLayout)
{
- emitSemanticsImpl(inst);
+ emitSemanticsImpl(inst, allowOffsetLayout);
}
void CLikeSourceEmitter::emitLayoutSemantics(IRInst* inst, char const* uniformSemanticSpelling)
@@ -3105,11 +3129,11 @@ void CLikeSourceEmitter::emitStruct(IRStructType* structType)
m_writer->emit(getName(structType));
- emitStructDeclarationsBlock(structType);
+ emitStructDeclarationsBlock(structType, false);
m_writer->emit(";\n\n");
}
-void CLikeSourceEmitter::emitStructDeclarationsBlock(IRStructType* structType)
+void CLikeSourceEmitter::emitStructDeclarationsBlock(IRStructType* structType, bool allowOffsetLayout)
{
m_writer->emit("\n{\n");
m_writer->indent();
@@ -3130,8 +3154,15 @@ void CLikeSourceEmitter::emitStructDeclarationsBlock(IRStructType* structType)
emitInterpolationModifiers(fieldKey, fieldType, nullptr);
}
+ if (allowOffsetLayout)
+ {
+ if (auto packOffsetDecoration = fieldKey->findDecoration<IRPackOffsetDecoration>())
+ {
+ emitPackOffsetModifier(fieldKey, fieldType, packOffsetDecoration);
+ }
+ }
emitType(fieldType, getName(fieldKey));
- emitSemantics(fieldKey);
+ emitSemantics(fieldKey, allowOffsetLayout);
m_writer->emit(";\n");
}
diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h
index bfe3dcc4e..393ab602c 100644
--- a/source/slang/slang-emit-c-like.h
+++ b/source/slang/slang-emit-c-like.h
@@ -292,6 +292,8 @@ public:
void emitType(IRType* type);
void emitType(IRType* type, Name* name, SourceLoc const& nameLoc);
void emitType(IRType* type, NameLoc const& nameAndLoc);
+ bool hasExplicitConstantBufferOffset(IRInst* cbufferType);
+ bool isSingleElementConstantBuffer(IRInst* cbufferType);
//
// Expressions
@@ -363,7 +365,7 @@ public:
void diagnoseUnhandledInst(IRInst* inst);
void emitInst(IRInst* inst);
- void emitSemantics(IRInst* inst);
+ void emitSemantics(IRInst* inst, bool allowOffsets = false);
void emitSemanticsUsingVarLayout(IRVarLayout* varLayout);
void emitLayoutSemantics(IRInst* inst, char const* uniformSemanticSpelling = "register");
@@ -405,7 +407,7 @@ public:
void emitStruct(IRStructType* structType);
// This is used independently of `emitStruct` by some GLSL parameter group
// output functionality
- void emitStructDeclarationsBlock(IRStructType* structType);
+ void emitStructDeclarationsBlock(IRStructType* structType, bool allowOffsetLayout);
void emitClass(IRClassType* structType);
/// Emit type attributes that should appear after, e.g., a `struct` keyword
@@ -413,7 +415,7 @@ public:
void emitInterpolationModifiers(IRInst* varInst, IRType* valueType, IRVarLayout* layout);
void emitMeshOutputModifiers(IRInst* varInst);
-
+ virtual void emitPackOffsetModifier(IRInst* /*varInst*/, IRType* /*valueType*/, IRPackOffsetDecoration* /*decoration*/) {};
/// Emit modifiers that should apply even for a declaration of an SSA temporary.
@@ -494,10 +496,11 @@ public:
virtual void emitPreModuleImpl() {}
virtual void emitRateQualifiersImpl(IRRate* rate) { SLANG_UNUSED(rate); }
- virtual void emitSemanticsImpl(IRInst* inst) { SLANG_UNUSED(inst); }
+ virtual void emitSemanticsImpl(IRInst* inst, bool allowOffsetLayout) { SLANG_UNUSED(inst); SLANG_UNUSED(allowOffsetLayout); }
virtual void emitSimpleFuncParamImpl(IRParam* param);
virtual void emitSimpleFuncParamsImpl(IRFunc* func);
virtual void emitInterpolationModifiersImpl(IRInst* varInst, IRType* valueType, IRVarLayout* layout) { SLANG_UNUSED(varInst); SLANG_UNUSED(valueType); SLANG_UNUSED(layout); }
+
virtual void emitMeshOutputModifiersImpl(IRInst* varInst) { SLANG_UNUSED(varInst) }
virtual void emitSimpleTypeImpl(IRType* type) = 0;
virtual void emitVarDecorationsImpl(IRInst* varDecl) { SLANG_UNUSED(varDecl); }
diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp
index a1e21f626..a6501b5be 100644
--- a/source/slang/slang-emit-cuda.cpp
+++ b/source/slang/slang-emit-cuda.cpp
@@ -745,9 +745,9 @@ void CUDASourceEmitter::emitSimpleValueImpl(IRInst* inst)
}
-void CUDASourceEmitter::emitSemanticsImpl(IRInst* inst)
+void CUDASourceEmitter::emitSemanticsImpl(IRInst* inst, bool allowOffsetLayout)
{
- Super::emitSemanticsImpl(inst);
+ Super::emitSemanticsImpl(inst, allowOffsetLayout);
}
void CUDASourceEmitter::emitInterpolationModifiersImpl(IRInst* varInst, IRType* valueType, IRVarLayout* layout)
diff --git a/source/slang/slang-emit-cuda.h b/source/slang/slang-emit-cuda.h
index 2ba7dd6a3..47f6eea06 100644
--- a/source/slang/slang-emit-cuda.h
+++ b/source/slang/slang-emit-cuda.h
@@ -69,7 +69,7 @@ protected:
virtual void emitPreModuleImpl() SLANG_OVERRIDE;
virtual void emitRateQualifiersImpl(IRRate* rate) SLANG_OVERRIDE;
- virtual void emitSemanticsImpl(IRInst* inst) SLANG_OVERRIDE;
+ virtual void emitSemanticsImpl(IRInst* inst, bool allowOffsetLayout) SLANG_OVERRIDE;
virtual void emitSimpleFuncImpl(IRFunc* func) SLANG_OVERRIDE;
virtual void emitSimpleFuncParamsImpl(IRFunc* func) SLANG_OVERRIDE;
virtual void emitInterpolationModifiersImpl(IRInst* varInst, IRType* valueType, IRVarLayout* layout) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 0abd78137..bc170dadc 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -339,16 +339,25 @@ void GLSLSourceEmitter::_emitGLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor
m_writer->emit("_S");
m_writer->emit(m_uniqueIDCounter++);
- m_writer->emit("\n{\n");
- m_writer->indent();
auto elementType = type->getElementType();
-
- emitType(elementType, "_data");
- m_writer->emit(";\n");
-
- m_writer->dedent();
- m_writer->emit("} ");
+ auto structType = as<IRStructType>(elementType);
+ if (!as<IRGLSLShaderStorageBufferType>(type) && structType)
+ {
+ // We need to emit the fields of the struct as individual variables
+ // in the constant buffer.
+ //
+ emitStructDeclarationsBlock(structType, true);
+ }
+ else
+ {
+ m_writer->emit("\n{\n");
+ m_writer->indent();
+ emitType(elementType, "_data");
+ m_writer->emit(";\n");
+ m_writer->dedent();
+ m_writer->emit("} ");
+ }
m_writer->emit(getName(varDecl));
@@ -794,7 +803,7 @@ void GLSLSourceEmitter::_maybeEmitGLSLBuiltin(IRGlobalParam* var, UnownedStringS
m_writer->emit("out");
m_writer->emit(" ");
m_writer->emit(elementTypeName);
- emitStructDeclarationsBlock(elementType);
+ emitStructDeclarationsBlock(elementType, false);
m_writer->emit(" ");
m_writer->emit(name);
emitArrayBrackets(arrayType);
@@ -1157,7 +1166,7 @@ void GLSLSourceEmitter::_emitGLSLPerVertexVaryingFragmentInput(IRGlobalParam* pa
//
_emitType(type, &arrayDeclarator);
- emitSemantics(param);
+ emitSemantics(param, false);
emitLayoutSemantics(param);
@@ -2372,6 +2381,17 @@ void GLSLSourceEmitter::emitInterpolationModifiersImpl(IRInst* varInst, IRType*
}
}
+void GLSLSourceEmitter::emitPackOffsetModifier(IRInst* varInst, IRType* valueType, IRPackOffsetDecoration* decoration)
+{
+ SLANG_UNUSED(varInst);
+ SLANG_UNUSED(valueType);
+
+ _requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_ARB_enhanced_layouts"));
+ m_writer->emit("layout(offset = ");
+ m_writer->emit(decoration->getRegisterOffset()->getValue() * 16 + decoration->getComponentOffset()->getValue() * 4);
+ m_writer->emit(")\n");
+}
+
void GLSLSourceEmitter::emitMeshOutputModifiersImpl(IRInst* varInst)
{
if(varInst->findDecoration<IRGLSLPrimitivesRateDecoration>())
diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h
index 99259463b..48c6971aa 100644
--- a/source/slang/slang-emit-glsl.h
+++ b/source/slang/slang-emit-glsl.h
@@ -33,6 +33,8 @@ protected:
virtual void emitRateQualifiersImpl(IRRate* rate) SLANG_OVERRIDE;
virtual void emitInterpolationModifiersImpl(IRInst* varInst, IRType* valueType, IRVarLayout* layout) SLANG_OVERRIDE;
+ virtual void emitPackOffsetModifier(IRInst* varInst, IRType* valueType, IRPackOffsetDecoration* decoration) SLANG_OVERRIDE;
+
virtual void emitMeshOutputModifiersImpl(IRInst* varInst) SLANG_OVERRIDE;
virtual void emitSimpleTypeImpl(IRType* type) SLANG_OVERRIDE;
virtual void emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index e07d9facc..434f0803e 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -208,10 +208,20 @@ void HLSLSourceEmitter::_emitHLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor
_emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain);
+ auto elementType = type->getElementType();
+ if (hasExplicitConstantBufferOffset(type))
+ {
+ // If the user has provided any explicit `packoffset` modifiers,
+ // we have to unwrap the struct and emit the fields directly.
+ emitStructDeclarationsBlock(as<IRStructType>(elementType), true);
+ m_writer->emit("\n");
+ return;
+ }
+
+
m_writer->emit("\n{\n");
m_writer->indent();
- auto elementType = type->getElementType();
emitType(elementType, getName(varDecl));
m_writer->emit(";\n");
@@ -989,7 +999,7 @@ void HLSLSourceEmitter::emitRateQualifiersImpl(IRRate* rate)
}
}
-void HLSLSourceEmitter::emitSemanticsImpl(IRInst* inst)
+void HLSLSourceEmitter::emitSemanticsImpl(IRInst* inst, bool allowOffsets)
{
if (auto semanticDecoration = inst->findDecoration<IRSemanticDecoration>())
{
@@ -997,6 +1007,33 @@ void HLSLSourceEmitter::emitSemanticsImpl(IRInst* inst)
m_writer->emit(semanticDecoration->getSemanticName());
return;
}
+ else if (auto packOffsetDecoration = inst->findDecoration<IRPackOffsetDecoration>())
+ {
+ if (allowOffsets)
+ {
+ m_writer->emit(" : packoffset(c");
+ m_writer->emit(packOffsetDecoration->getRegisterOffset()->getValue());
+ if (packOffsetDecoration->getComponentOffset())
+ {
+ switch (packOffsetDecoration->getComponentOffset()->getValue())
+ {
+ case 0:
+ break;
+ case 1:
+ m_writer->emit(".y");
+ break;
+ case 2:
+ m_writer->emit(".z");
+ break;
+ case 3:
+ m_writer->emit(".w");
+ break;
+ }
+ }
+ m_writer->emit(")");
+ return;
+ }
+ }
if( auto readAccessSemantic = inst->findDecoration<IRStageReadAccessDecoration>())
_emitStageAccessSemantic(readAccessSemantic, "read");
@@ -1114,6 +1151,14 @@ void HLSLSourceEmitter::emitInterpolationModifiersImpl(IRInst* varInst, IRType*
}
}
+void HLSLSourceEmitter::emitPackOffsetModifier(IRInst* varInst, IRType* valueType, IRPackOffsetDecoration* layout)
+{
+ SLANG_UNUSED(varInst);
+ SLANG_UNUSED(valueType);
+ SLANG_UNUSED(layout);
+ // We emit packoffset as a semantic in `emitSemantic`, so nothing to do here.
+}
+
void HLSLSourceEmitter::emitMeshOutputModifiersImpl(IRInst* varInst)
{
if(auto modifier = varInst->findDecoration<IRMeshOutputDecoration>())
diff --git a/source/slang/slang-emit-hlsl.h b/source/slang/slang-emit-hlsl.h
index 0a4e7fde8..d69e054b4 100644
--- a/source/slang/slang-emit-hlsl.h
+++ b/source/slang/slang-emit-hlsl.h
@@ -36,9 +36,11 @@ protected:
virtual void emitFrontMatterImpl(TargetRequest* targetReq) SLANG_OVERRIDE;
virtual void emitRateQualifiersImpl(IRRate* rate) SLANG_OVERRIDE;
- virtual void emitSemanticsImpl(IRInst* inst) SLANG_OVERRIDE;
+ virtual void emitSemanticsImpl(IRInst* inst, bool allowOffsets) SLANG_OVERRIDE;
virtual void emitSimpleFuncParamImpl(IRParam* param) SLANG_OVERRIDE;
virtual void emitInterpolationModifiersImpl(IRInst* varInst, IRType* valueType, IRVarLayout* layout) SLANG_OVERRIDE;
+ virtual void emitPackOffsetModifier(IRInst* varInst, IRType* valueType, IRPackOffsetDecoration* decoration) SLANG_OVERRIDE;
+
virtual void emitMeshOutputModifiersImpl(IRInst* varInst) SLANG_OVERRIDE;
virtual void emitSimpleTypeImpl(IRType* type) SLANG_OVERRIDE;
virtual void emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 62a1365c0..88b616996 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -54,6 +54,7 @@
#include "slang-ir-wrap-structured-buffers.h"
#include "slang-ir-liveness.h"
#include "slang-ir-glsl-liveness.h"
+#include "slang-ir-legalize-uniform-buffer-load.h"
#include "slang-ir-string-hash.h"
#include "slang-ir-simplify-for-emit.h"
#include "slang-ir-pytorch-cpp-binding.h"
@@ -846,6 +847,11 @@ Result linkAndOptimizeIR(
// arrays that the emitters can deal with.
legalizeMeshOutputTypes(irModule);
+ if (isKhronosTarget(targetRequest) || target == CodeGenTarget::HLSL)
+ {
+ legalizeUniformBufferLoad(irModule);
+ }
+
// Lower all bit_cast operations on complex types into leaf-level
// bit_cast on basic types.
lowerBitCast(targetRequest, irModule);
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index b00972cce..ffdd2b337 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -661,7 +661,6 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
INST(PublicDecoration, public, 0, 0)
INST(HLSLExportDecoration, hlslExport, 0, 0)
INST(PatchConstantFuncDecoration, patchConstantFunc, 1, 0)
-
INST(OutputControlPointsDecoration, outputControlPoints, 1, 0)
INST(OutputTopologyDecoration, outputTopology, 1, 0)
INST(PartitioningDecoration, partioning, 1, 0)
@@ -782,6 +781,7 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
INST_RANGE(StageAccessDecoration, StageReadAccessDecoration, StageWriteAccessDecoration)
INST(SemanticDecoration, semantic, 2, 0)
+ INST(PackOffsetDecoration, packoffset, 2, 0)
INST(SPIRVOpDecoration, spirvOpDecoration, 1, 0)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 4495d1a3d..9c31798e0 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -1116,6 +1116,18 @@ struct IRSemanticDecoration : public IRDecoration
int getSemanticIndex() { return int(getIntVal(getSemanticIndexOperand())); }
};
+struct IRPackOffsetDecoration : IRDecoration
+{
+ enum
+ {
+ kOp = kIROp_PackOffsetDecoration
+ };
+ IR_LEAF_ISA(PackOffsetDecoration)
+
+ IRIntLit* getRegisterOffset() { return cast<IRIntLit>(getOperand(0)); }
+ IRIntLit* getComponentOffset() { return cast<IRIntLit>(getOperand(1)); }
+};
+
struct IRStageAccessDecoration : public IRDecoration
{
IR_PARENT_ISA(StageAccessDecoration)
diff --git a/source/slang/slang-ir-legalize-uniform-buffer-load.cpp b/source/slang/slang-ir-legalize-uniform-buffer-load.cpp
new file mode 100644
index 000000000..6acf38ee6
--- /dev/null
+++ b/source/slang/slang-ir-legalize-uniform-buffer-load.cpp
@@ -0,0 +1,50 @@
+#include "slang-ir-legalize-uniform-buffer-load.h"
+
+namespace Slang
+{
+void legalizeUniformBufferLoad(IRModule* module)
+{
+ List<IRLoad*> workList;
+ for (auto globalInst : module->getGlobalInsts())
+ {
+ if (auto func = as<IRGlobalValueWithCode>(globalInst))
+ {
+ for (auto block : func->getBlocks())
+ {
+ for (auto inst : block->getChildren())
+ {
+ if (auto load = as<IRLoad>(inst))
+ {
+ auto uniformBufferType = as<IRConstantBufferType>(load->getPtr()->getDataType());
+ if (!uniformBufferType)
+ continue;
+ workList.add(load);
+ }
+ }
+ }
+ }
+ }
+
+ IRBuilder builder(module);
+ for (auto load : workList)
+ {
+ auto uniformBufferType = as<IRConstantBufferType>(load->getPtr()->getDataType());
+ SLANG_ASSERT(uniformBufferType);
+ auto structType = as<IRStructType>(uniformBufferType->getElementType());
+ if (!structType)
+ continue;
+ builder.setInsertBefore(load);
+ List<IRInst*> fieldLoads;
+ for (auto field : structType->getFields())
+ {
+ auto fieldAddr = builder.emitFieldAddress(
+ builder.getPtrType(field->getFieldType()), load->getPtr(), field->getKey());
+ auto fieldLoad = builder.emitLoad(fieldAddr);
+ fieldLoads.add(fieldLoad);
+ }
+ auto makeStruct = builder.emitMakeStruct(structType, fieldLoads);
+ load->replaceUsesWith(makeStruct);
+ }
+}
+
+}
diff --git a/source/slang/slang-ir-legalize-uniform-buffer-load.h b/source/slang/slang-ir-legalize-uniform-buffer-load.h
new file mode 100644
index 000000000..fff1867b6
--- /dev/null
+++ b/source/slang/slang-ir-legalize-uniform-buffer-load.h
@@ -0,0 +1,12 @@
+// slang-ir-legalize-uniform-buffer-load.h
+#pragma once
+
+#include "slang-ir-insts.h"
+
+namespace Slang
+{
+ struct IRModule;
+
+ // Legalize a load(IRUniformParameterGroupType) into a makeStruct(load(fieldAddr),...) for glsl.
+ void legalizeUniformBufferLoad(IRModule* module);
+}
diff --git a/source/slang/slang-ir-use-uninitialized-out-param.cpp b/source/slang/slang-ir-use-uninitialized-out-param.cpp
index 64f5f8bd3..977876c6b 100644
--- a/source/slang/slang-ir-use-uninitialized-out-param.cpp
+++ b/source/slang/slang-ir-use-uninitialized-out-param.cpp
@@ -63,6 +63,7 @@ namespace Slang
addresses.add(use->getUser());
break;
case kIROp_Store:
+ case kIROp_SwizzledStore:
// If we see a store of this address, add it to stores set.
if (use == use->getUser()->getOperands())
stores.add(StoreSite{ use->getUser(), addr });
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 95240a26c..506e96c81 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -430,6 +430,11 @@ bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, I
if (canAddressesPotentiallyAlias(func, as<IRStore>(inst)->getPtr(), addr))
return true;
break;
+ case kIROp_SwizzledStore:
+ // If the target of the swizzled store inst may overlap addr, return true.
+ if (canAddressesPotentiallyAlias(func, as<IRSwizzledStore>(inst)->getDest(), addr))
+ return true;
+ break;
case kIROp_Call:
{
auto call = as<IRCall>(inst);
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 1511615ed..de2d5aff2 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -7648,6 +7648,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
irAggType,
fieldKey,
fieldType);
+
+ if (auto packOffsetModifier = fieldDecl->findModifier<HLSLPackOffsetSemantic>())
+ {
+ lowerPackOffsetModifier(fieldKey, packOffsetModifier);
+ }
}
// There may be members not handled by the above logic (e.g.,
@@ -7663,6 +7668,36 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return LoweredValInfo::simple(finishOuterGenerics(subBuilder, irAggType, outerGeneric));
}
+ void lowerPackOffsetModifier(IRInst* inst, HLSLPackOffsetSemantic* semantic)
+ {
+ auto builder = getBuilder();
+ int registerOffset = stringToInt(semantic->registerName.getName()->text.getUnownedSlice().tail(1));
+ int componentOffset = 0;
+ if (semantic->componentMask.getContentLength() != 0)
+ {
+ switch (semantic->componentMask.getContent()[0])
+ {
+ case 'x':
+ componentOffset = 0;
+ break;
+ case 'y':
+ componentOffset = 1;
+ break;
+ case 'z':
+ componentOffset = 2;
+ break;
+ case 'w':
+ componentOffset = 3;
+ break;
+ }
+ }
+ builder->addDecoration(
+ inst,
+ kIROp_PackOffsetDecoration,
+ builder->getIntValue(builder->getIntType(), registerOffset),
+ builder->getIntValue(builder->getIntType(), componentOffset));
+ }
+
void lowerRayPayloadAccessModifier(IRInst* inst, RayPayloadAccessSemantic* semantic, IROp op)
{
auto builder = getBuilder();
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index 8437d9a6c..353c6e57f 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -81,6 +81,8 @@ enum class OptionKind
LineDirectiveMode,
Optimization,
Obfuscate,
+ GLSLForceScalarLayout,
+ EnableEffectAnnotations,
// Downstream
@@ -415,6 +417,13 @@ void initCommandOptions(CommandOptions& options)
"for GLSL output." },
{ OptionKind::Optimization, "-O...", "-O<optimization-level>", "Set the optimization level."},
{ OptionKind::Obfuscate, "-obfuscate", nullptr, "Remove all source file information from outputs." },
+ { OptionKind::GLSLForceScalarLayout,
+ "-force-glsl-scalar-layout",
+ nullptr,
+ "Force using scalar block layout for uniform and shader storage buffers in GLSL output."},
+ { OptionKind::EnableEffectAnnotations,
+ "-enable-effect-annotations",
+ "Enables support for legacy effect annotation syntax."},
};
_addOptions(makeConstArrayView(targetOpts), options);
@@ -656,7 +665,7 @@ struct OptionsParser
SlangTargetFlags targetFlags = 0;
int targetID = -1;
FloatingPointMode floatingPointMode = FloatingPointMode::Default;
-
+ bool forceGLSLScalarLayout = false;
List<CapabilityAtom> capabilityAtoms;
// State for tracking command-line errors
@@ -1831,6 +1840,16 @@ struct OptionsParser
setFloatingPointMode(getCurrentTarget(), FloatingPointMode(value));
break;
}
+ case OptionKind::GLSLForceScalarLayout:
+ {
+ getCurrentTarget()->forceGLSLScalarLayout = true;
+ break;
+ }
+ case OptionKind::EnableEffectAnnotations:
+ {
+ compileRequest->setEnableEffectAnnotations(true);
+ break;
+ }
case OptionKind::Optimization:
{
UnownedStringSlice levelSlice = argValue.getUnownedSlice().tail(2);
@@ -2525,6 +2544,10 @@ struct OptionsParser
{
compileRequest->setTargetFloatingPointMode(targetID, SlangFloatingPointMode(rawTarget.floatingPointMode));
}
+ if (rawTarget.forceGLSLScalarLayout)
+ {
+ compileRequest->setTargetForceGLSLScalarBufferLayout(targetID, true);
+ }
}
if(defaultMatrixLayoutMode != SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index bd33b6f37..721d4204d 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -594,12 +594,6 @@ LayoutSemanticInfo ExtractLayoutSemanticInfo(
spaceToken->loc,
getSink(context));
- // TODO: handle component mask part of things...
- if( semantic->componentMask.hasContent())
- {
- getSink(context)->diagnose(semantic->componentMask, Diagnostics::componentMaskNotSupported);
- }
-
return info;
}
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 88cc6fac2..78433a96f 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -77,6 +77,11 @@ namespace Slang
Postfix,
};
+ struct ParserOptions
+ {
+ bool enableEffectAnnotations = false;
+ };
+
// TODO: implement two pass parsing for file reference and struct type recognition
class Parser
@@ -103,6 +108,7 @@ namespace Slang
TokenReader tokenReader;
DiagnosticSink* sink;
SourceLoc lastErrorLoc;
+ ParserOptions options;
int genericDepth = 0;
@@ -150,11 +156,13 @@ namespace Slang
ASTBuilder* inAstBuilder,
TokenSpan const& _tokens,
DiagnosticSink * sink,
- Scope* outerScope)
+ Scope* outerScope,
+ ParserOptions inOptions)
: tokenReader(_tokens)
, astBuilder(inAstBuilder)
, sink(sink)
, outerScope(outerScope)
+ , options(inOptions)
{}
Parser(const Parser & other) = default;
@@ -1750,6 +1758,51 @@ namespace Slang
case TokenType::LParent:
break;
+ case TokenType::OpLess:
+ {
+ if (parser->options.enableEffectAnnotations)
+ {
+ // If we are in a context where effect annotations are allowed,
+ // then we need to disambiguate the content after "<" to see if it
+ // should be parsed as an annotation or generic argument list.
+ // If we can determine the content inside a `<>` is an annotation,
+ // we will skip the tokens inside the angle brackets.
+ //
+ if (parser->tokenReader.peekTokenType() == TokenType::OpLess)
+ {
+ if (parser->LookAheadToken("let", 1))
+ {
+ // If we see `<let` then we are looking at a generic arg list.
+ }
+ else if (parser->LookAheadToken(":", 2))
+ {
+ // If we see a "< xxx :", we can also parse it as a generic arg list.
+ }
+ else
+ {
+ // Otherwise, we may be looking at an effect annotation.
+ // For now we just skip tokens until we see `>`, if we see any `;` in between,
+ // we can conclude that this is an annotation.
+ TokenReader tempReader = parser->tokenReader;
+ bool foundSemicolon = false;
+ while (tempReader.peekTokenType() != TokenType::OpGreater &&
+ tempReader.peekTokenType() != TokenType::EndOfFile)
+ {
+ if (tempReader.peekTokenType() == TokenType::Semicolon)
+ foundSemicolon = true;
+ tempReader.advanceToken();
+ }
+ if (foundSemicolon)
+ {
+ parser->tokenReader = tempReader;
+ parser->ReadToken(TokenType::OpGreater);
+ }
+ }
+ }
+ }
+
+ }
+ break;
default:
break;
}
@@ -2570,7 +2623,6 @@ namespace Slang
&& !initDeclarator.initializer
&& !initDeclarator.semantics.first)
{
- // Looks like a function, so parse it like one.
UnwrapDeclarator(parser->astBuilder, initDeclarator, &declaratorInfo);
return parseTraditionalFuncDecl(parser, declaratorInfo);
}
@@ -2714,8 +2766,6 @@ namespace Slang
parseHLSLRegisterNameAndOptionalComponentMask(parser, semantic);
parser->ReadToken(TokenType::RParent);
-
- parser->sink->diagnose(semantic, Diagnostics::packOffsetNotSupported);
}
static RayPayloadAccessSemantic* _parseRayPayloadAccessSemantic(Parser* parser, RayPayloadAccessSemantic* semantic)
@@ -6155,7 +6205,7 @@ namespace Slang
NamePool* namePool,
SourceLanguage sourceLanguage)
{
- Parser parser(astBuilder, tokens, sink, outerScope);
+ Parser parser(astBuilder, tokens, sink, outerScope, ParserOptions{});
parser.currentScope = outerScope;
parser.namePool = namePool;
parser.sourceLanguage = sourceLanguage;
@@ -6170,7 +6220,10 @@ namespace Slang
DiagnosticSink* sink,
Scope* outerScope)
{
- Parser parser(astBuilder, tokens, sink, outerScope);
+ ParserOptions options = {};
+ options.enableEffectAnnotations = translationUnit->compileRequest->getLinkage()->getEnableEffectAnnotations();
+
+ Parser parser(astBuilder, tokens, sink, outerScope, options);
parser.namePool = translationUnit->getNamePool();
parser.sourceLanguage = translationUnit->sourceLanguage;
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index 0f1341afd..79236fc48 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -3183,6 +3183,35 @@ RefPtr<VarLayout> StructTypeLayoutBuilder::addField(
return fieldLayout;
}
+RefPtr<VarLayout> StructTypeLayoutBuilder::addExplicitUniformField(DeclRef<VarDeclBase> field, TypeLayoutResult fieldResult)
+{
+ auto packoffsetModifier = field.getDecl()->findModifier<HLSLPackOffsetSemantic>();
+ if (!packoffsetModifier)
+ return nullptr;
+
+ RefPtr<VarLayout> fieldLayout = new VarLayout();
+ fieldLayout->varDecl = field;
+ fieldLayout->typeLayout = fieldResult.layout;
+ m_typeLayout->fields.add(fieldLayout);
+ if (field)
+ {
+ m_typeLayout->mapVarToLayout.add(field.getDecl(), fieldLayout);
+ }
+ UInt uniformOffset = packoffsetModifier->uniformOffset;
+ if (fieldResult.layout->FindResourceInfo(LayoutResourceKind::Uniform))
+ {
+ fieldLayout->AddResourceInfo(LayoutResourceKind::Uniform)->index = uniformOffset;
+ }
+ UniformLayoutInfo fieldInfo = fieldResult.info.getUniformLayout();
+ auto uniformInfo = m_info;
+ m_rules->AddStructField(&uniformInfo, fieldInfo);
+ m_info.alignment = uniformInfo.alignment;
+ m_info.size.raw = Math::Max(
+ m_info.size.getFiniteValue(),
+ (size_t)(uniformOffset + fieldResult.layout->FindResourceInfo(LayoutResourceKind::Uniform)->count.getFiniteValue()));
+ return fieldLayout;
+}
+
RefPtr<VarLayout> StructTypeLayoutBuilder::addField(
DeclRef<VarDeclBase> field,
RefPtr<TypeLayout> fieldTypeLayout)
@@ -3684,8 +3713,29 @@ static TypeLayoutResult _createTypeLayout(
typeLayoutBuilder.beginLayout(type, rules);
auto typeLayout = typeLayoutBuilder.getTypeLayout();
+
+ // First, add all fields with explicit offsets.
+ for (auto field : getFields(structDeclRef, MemberFilterStyle::Instance))
+ {
+ // If the field has an explicit offset, then we will
+ // use that to place it.
+ //
+ if (auto packOffsetModifier = field.getDecl()->findModifier<HLSLPackOffsetSemantic>())
+ {
+ TypeLayoutResult fieldResult = _createTypeLayout(
+ context,
+ getType(context.astBuilder, field),
+ field.getDecl());
+ typeLayoutBuilder.addExplicitUniformField(field, fieldResult);
+ continue;
+ }
+
+ }
for (auto field : getFields(structDeclRef, MemberFilterStyle::Instance))
{
+ if (auto packOffsetModifier = field.getDecl()->findModifier<HLSLPackOffsetSemantic>())
+ continue;
+
// The fields of a `struct` type may include existential (interface)
// types (including as nested sub-fields), and any types present
// in those fields will need to be specialized based on the
diff --git a/source/slang/slang-type-layout.h b/source/slang/slang-type-layout.h
index e0b391232..0b6dd42d8 100644
--- a/source/slang/slang-type-layout.h
+++ b/source/slang/slang-type-layout.h
@@ -1138,6 +1138,10 @@ public:
DeclRef<VarDeclBase> field,
TypeLayoutResult fieldResult);
+ RefPtr<VarLayout> addExplicitUniformField(
+ DeclRef<VarDeclBase> field,
+ TypeLayoutResult fieldResult);
+
/// Add a field to the struct type layout.
///
/// One of the `beginLayout*()` functions must have been called previously.
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 9c75aa63e..ec5a7084e 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -608,6 +608,12 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Session::createSession(
{
linkage->setFileSystem(desc.fileSystem);
}
+
+ if (desc.structureSize >= offsetof(slang::SessionDesc, enableEffectAnnotations))
+ {
+ linkage->setEnableEffectAnnotations(desc.enableEffectAnnotations);
+ }
+
*outSession = asExternal(linkage.detach());
return SLANG_OK;
}
@@ -4804,6 +4810,11 @@ void EndToEndCompileRequest::addPreprocessorDefine(const char* key, const char*
getLinkage()->addPreprocessorDefine(key, value);
}
+void EndToEndCompileRequest::setEnableEffectAnnotations(bool value)
+{
+ getLinkage()->setEnableEffectAnnotations(value);
+}
+
char const* EndToEndCompileRequest::getDiagnosticOutput()
{
return m_diagnosticOutput.begin();
diff --git a/tests/bindings/glsl-parameter-blocks.slang.glsl b/tests/bindings/glsl-parameter-blocks.slang.glsl
index 03e4e8774..fbeddb905 100644
--- a/tests/bindings/glsl-parameter-blocks.slang.glsl
+++ b/tests/bindings/glsl-parameter-blocks.slang.glsl
@@ -1,31 +1,50 @@
#version 450
layout(row_major) uniform;
layout(row_major) buffer;
+
+#line 3 "tests/bindings/glsl-parameter-blocks.slang"
struct Test_0
{
vec4 a_0;
};
+
+#line 7
layout(binding = 0)
layout(std140) uniform _S1
{
- Test_0 _data;
-} gTest_0;
+ vec4 a_0;
+}gTest_0;
+
+#line 3
layout(binding = 1)
uniform texture2D gTest_t_0;
+
+#line 1237 "core.meta.slang"
layout(binding = 2)
uniform sampler gTest_s_0;
+
+#line 89 "core"
layout(location = 0)
out vec4 _S2;
+
+#line 902 "core.meta.slang"
layout(location = 0)
in vec2 _S3;
+
+#line 12 "tests/bindings/glsl-parameter-blocks.slang"
void main()
{
vec4 _S4 = (texture(sampler2D(gTest_t_0,gTest_s_0), (_S3)));
- _S2 = gTest_0._data.a_0 + _S4;
+
+#line 14
+ _S2 = gTest_0.a_0 + _S4;
+
+#line 14
return;
}
+
diff --git a/tests/bugs/gh-941.slang.glsl b/tests/bugs/gh-941.slang.glsl
index d3c29820d..4330ece53 100644
--- a/tests/bugs/gh-941.slang.glsl
+++ b/tests/bugs/gh-941.slang.glsl
@@ -14,7 +14,8 @@ layout(binding = 2)
layout(std140)
uniform _S1
{
- SLANG_ParameterGroup_C_0 _data;
+ vec2 uv_0;
+ uint index_0;
} C_0;
layout(binding = 0)
@@ -30,9 +31,9 @@ void main()
{
vec4 _S3 = texture(
sampler2D(
- t_0[C_0._data.index_0],
+ t_0[C_0.index_0],
s_0),
- C_0._data.uv_0);
+ C_0.uv_0);
_S2 = _S3;
return;
} \ No newline at end of file
diff --git a/tests/cross-compile/array-of-buffers.slang.glsl b/tests/cross-compile/array-of-buffers.slang.glsl
index 4ff86f36e..62990033e 100644
--- a/tests/cross-compile/array-of-buffers.slang.glsl
+++ b/tests/cross-compile/array-of-buffers.slang.glsl
@@ -9,7 +9,7 @@ struct SLANG_ParameterGroup_C_0
layout(binding = 0)
layout(std140) uniform _S1
{
- SLANG_ParameterGroup_C_0 _data;
+ uint index_0;
} C_0;
struct S_0
{
@@ -19,7 +19,7 @@ struct S_0
layout(binding = 1)
layout(std140) uniform _S2
{
- S_0 _data;
+ vec4 f_0;
} cb_0[3];
layout(std430, binding = 2) readonly buffer _S3 {
S_0 _data[];
@@ -36,9 +36,9 @@ out vec4 _S6;
void main()
{
- S_0 _S7 = ((sb1_0[C_0._data.index_0])._data[(C_0._data.index_0)]);
- vec4 _S8 = cb_0[C_0._data.index_0]._data.f_0 + _S7.f_0;
- uint _S9 = ((bb_0[C_0._data.index_0])._data[(int(C_0._data.index_0 * 4U))/4]);
- _S6 = _S8 + ((sb2_0[C_0._data.index_0])._data[(C_0._data.index_0)]) + vec4(float(_S9));
+ S_0 _S7 = ((sb1_0[C_0.index_0])._data[(C_0.index_0)]);
+ vec4 _S8 = cb_0[C_0.index_0].f_0 + _S7.f_0;
+ uint _S9 = ((bb_0[C_0.index_0])._data[(int(C_0.index_0 * 4U))/4]);
+ _S6 = _S8 + ((sb2_0[C_0.index_0])._data[(C_0.index_0)]) + vec4(float(_S9));
return;
}
diff --git a/tests/cross-compile/glsl-empty-struct-param-field.slang.glsl b/tests/cross-compile/glsl-empty-struct-param-field.slang.glsl
index 0ff895179..acf0a6fe9 100644
--- a/tests/cross-compile/glsl-empty-struct-param-field.slang.glsl
+++ b/tests/cross-compile/glsl-empty-struct-param-field.slang.glsl
@@ -11,13 +11,13 @@ struct P_0
layout(binding = 0)
layout(std140) uniform _S1
{
- P_0 _data;
+ vec4 param_0;
} pblock_0;
layout(location = 0)
out vec4 _S2;
void main()
{
- _S2 = pblock_0._data.param_0;
+ _S2 = pblock_0.param_0;
return;
} \ No newline at end of file
diff --git a/tests/cross-compile/half-conversion.slang.glsl b/tests/cross-compile/half-conversion.slang.glsl
index fb51809b4..b062f67b4 100644
--- a/tests/cross-compile/half-conversion.slang.glsl
+++ b/tests/cross-compile/half-conversion.slang.glsl
@@ -9,7 +9,7 @@ struct SLANG_ParameterGroup_C_0
layout(binding = 0)
layout(std140) uniform _S1
{
- SLANG_ParameterGroup_C_0 _data;
+ uvec4 u_0;
} C_0;
vec4 f16tof32_0(uvec4 value_0)
{
@@ -35,6 +35,6 @@ out vec4 _S2;
void main()
{
- _S2 = f16tof32_0(C_0._data.u_0);
+ _S2 = f16tof32_0(C_0.u_0);
return;
}
diff --git a/tests/cross-compile/texture-load.slang.glsl b/tests/cross-compile/texture-load.slang.glsl
index bb4514bad..d9145cdbf 100644
--- a/tests/cross-compile/texture-load.slang.glsl
+++ b/tests/cross-compile/texture-load.slang.glsl
@@ -17,7 +17,7 @@ layout(binding = 2)
layout(std140)
uniform _S1
{
- SLANG_ParameterGroup_C_0 _data;
+ ivec2 pos_0;
} C_0;
layout(binding = 0)
@@ -30,7 +30,7 @@ uniform image2D outputTexture_0;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
- ivec3 _S2 = ivec3(C_0._data.pos_0, 0);
+ ivec3 _S2 = ivec3(C_0.pos_0, 0);
vec2 tmp_0 = texelFetch(
inputTexture_0,
@@ -39,7 +39,7 @@ void main()
imageStore(
outputTexture_0,
- ivec2(uvec2(C_0._data.pos_0)),
+ ivec2(uvec2(C_0.pos_0)),
vec4(tmp_0, float(0), float(0)));
return;
diff --git a/tests/cross-compile/unknown-image-format.slang.glsl b/tests/cross-compile/unknown-image-format.slang.glsl
index 5ccc30767..e541a8b17 100644
--- a/tests/cross-compile/unknown-image-format.slang.glsl
+++ b/tests/cross-compile/unknown-image-format.slang.glsl
@@ -14,7 +14,7 @@ struct SLANG_ParameterGroup_C_0
layout(binding = 2)
layout(std140) uniform _S1
{
- SLANG_ParameterGroup_C_0 _data;
+ uvec2 index_0;
} C_0;
layout(binding = 0)
@@ -44,22 +44,22 @@ out vec4 _S2;
void main()
{
- float _S3 = (imageLoad((gNoFormat_0), ivec2((C_0._data.index_0))).x);
+ float _S3 = (imageLoad((gNoFormat_0), ivec2((C_0.index_0))).x);
vec4 _S4 = vec4(_S3);
- float _S5 = (imageLoad((gExplicitFormat_0), ivec2((C_0._data.index_0))).x);
+ float _S5 = (imageLoad((gExplicitFormat_0), ivec2((C_0.index_0))).x);
vec4 result_0 = _S4 + _S5;
- vec4 _S6 = (imageLoad((gBlock_noFormat_0), ivec2((C_0._data.index_0))));
+ vec4 _S6 = (imageLoad((gBlock_noFormat_0), ivec2((C_0.index_0))));
vec4 result_1 = result_0 + _S6;
- vec4 _S7 = (imageLoad((gBlock_explicitFormat_0), ivec2((C_0._data.index_0))));
+ vec4 _S7 = (imageLoad((gBlock_explicitFormat_0), ivec2((C_0.index_0))));
vec4 result_2 = result_1 + _S7;
- vec4 _S8 = (imageLoad((entryPointParams_noFormat_0), ivec2((C_0._data.index_0))));
+ vec4 _S8 = (imageLoad((entryPointParams_noFormat_0), ivec2((C_0.index_0))));
vec4 result_3 = result_2 + _S8;
- vec4 _S9 = (imageLoad((entryPointParams_explicitFormat_0), ivec2((C_0._data.index_0))));
+ vec4 _S9 = (imageLoad((entryPointParams_explicitFormat_0), ivec2((C_0.index_0))));
_S2 = result_3 + _S9;
return;
diff --git a/tests/cross-compile/vector-comparison.slang.glsl b/tests/cross-compile/vector-comparison.slang.glsl
index 3e6f7b9c2..f7c28203e 100644
--- a/tests/cross-compile/vector-comparison.slang.glsl
+++ b/tests/cross-compile/vector-comparison.slang.glsl
@@ -10,7 +10,8 @@ struct Param_0
layout(binding = 0)
layout(std140) uniform _S1
{
- Param_0 _data;
+ vec4 a_0;
+ vec4 b_0;
} params_0;
layout(location = 0)
out vec4 _S2;
@@ -20,6 +21,6 @@ void main()
const vec4 _S3 = vec4(2.0);
const vec4 _S4 = vec4(3.0);
- _S2 = mix(_S4, _S3, (equal(params_0._data.a_0,params_0._data.b_0))) + mix(_S4, _S3, (lessThan(params_0._data.a_0,params_0._data.b_0))) + mix(_S4, _S3, (greaterThan(params_0._data.a_0,params_0._data.b_0))) + mix(_S4, _S3, (lessThanEqual(params_0._data.a_0,params_0._data.b_0))) + mix(_S4, _S3, (greaterThanEqual(params_0._data.a_0,params_0._data.b_0))) + mix(_S4, _S3, (notEqual(params_0._data.a_0,params_0._data.b_0)));
+ _S2 = mix(_S4, _S3, (equal(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (lessThan(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (greaterThan(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (lessThanEqual(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (greaterThanEqual(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (notEqual(params_0.a_0,params_0.b_0)));
return;
}
diff --git a/tests/cross-compile/vk-push-constant-set.slang.glsl b/tests/cross-compile/vk-push-constant-set.slang.glsl
index 189b14caf..7a2ce4db0 100644
--- a/tests/cross-compile/vk-push-constant-set.slang.glsl
+++ b/tests/cross-compile/vk-push-constant-set.slang.glsl
@@ -9,13 +9,13 @@ struct S_0
layout(push_constant)
layout(std140) uniform _S1
{
- S_0 _data;
+ vec4 v_0;
} x_0;
layout(binding = 0, set = 0)
layout(std140) uniform _S2
{
- S_0 _data;
+ vec4 v_0;
} y_0;
layout(location = 0)
@@ -23,6 +23,6 @@ out vec4 _S3;
void main()
{
- _S3 = x_0._data.v_0 + y_0._data.v_0;
+ _S3 = x_0.v_0 + y_0.v_0;
return;
}
diff --git a/tests/diagnostics/packoffset.slang b/tests/diagnostics/packoffset.slang
deleted file mode 100644
index b5669c410..000000000
--- a/tests/diagnostics/packoffset.slang
+++ /dev/null
@@ -1,11 +0,0 @@
-// packoffset.slang
-//DIAGNOSTIC_TEST:SIMPLE:-target hlsl
-
-// use of `packoffset` (not supported):
-cbuffer B
-{
- float4 x : packoffset(c0);
-}
-
-void main()
-{} \ No newline at end of file
diff --git a/tests/diagnostics/packoffset.slang.expected b/tests/diagnostics/packoffset.slang.expected
deleted file mode 100644
index 701457fe7..000000000
--- a/tests/diagnostics/packoffset.slang.expected
+++ /dev/null
@@ -1,8 +0,0 @@
-result code = -1
-standard error = {
-tests/diagnostics/packoffset.slang(7): error 39012: explicit 'packoffset' bindings are not yet supported in Slang
- float4 x : packoffset(c0);
- ^~~~~~~~~~
-}
-standard output = {
-}
diff --git a/tests/diagnostics/register-bindings.slang b/tests/diagnostics/register-bindings.slang
index 263329bf6..5c78cb10b 100644
--- a/tests/diagnostics/register-bindings.slang
+++ b/tests/diagnostics/register-bindings.slang
@@ -15,8 +15,6 @@ SamplerState c : register(s0, s1);
// No space index given after `space`:
SamplerState d : register(s2, space);
-// use of a component mask (not supported):
-Texture2D e : register(t3.x);
void main()
{} \ No newline at end of file
diff --git a/tests/diagnostics/register-bindings.slang.expected b/tests/diagnostics/register-bindings.slang.expected
index e71f58b13..74e9917d3 100644
--- a/tests/diagnostics/register-bindings.slang.expected
+++ b/tests/diagnostics/register-bindings.slang.expected
@@ -12,9 +12,6 @@ SamplerState c : register(s0, s1);
tests/diagnostics/register-bindings.slang(16): error 39010: expected a register space index after 'space'
SamplerState d : register(s2, space);
^~~~~
-tests/diagnostics/register-bindings.slang(19): error 39011: explicit register component masks are not yet supported in Slang
-Texture2D e : register(t3.x);
- ^
}
standard output = {
}
diff --git a/tests/hlsl/packoffset.slang b/tests/hlsl/packoffset.slang
new file mode 100644
index 000000000..94273d8d7
--- /dev/null
+++ b/tests/hlsl/packoffset.slang
@@ -0,0 +1,33 @@
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -output-using-type
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -output-using-type
+//TEST:SIMPLE(filecheck=HLSL): -target hlsl -profile cs_5_0 -entry computeMain -line-directive-mode none
+//TEST:SIMPLE(filecheck=GLSL): -target glsl -profile glsl_450 -stage compute -entry computeMain -line-directive-mode none
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<float> outputBuffer;
+
+//TEST_INPUT:set Constants.v0={1.0,2.0,3.0,4.0}
+//TEST_INPUT:set Constants.v1={5.0,6.0,7.0}
+//TEST_INPUT:set Constants.v2=8.0
+
+cbuffer Constants
+{
+ float4 v0 : packoffset(c0);
+ float3 v1 : packoffset(c1);
+ float v2 : packoffset(c1.w);
+};
+// HLSL: cbuffer
+// HLSL: {
+// HLSL: {{.*}} : packoffset(c0);
+// HLSL: {{.*}} : packoffset(c1);
+// HLSL: {{.*}} : packoffset(c1.w);
+// HLSL: }
+// GLSL: layout(offset = 0)
+// GLSL: layout(offset = 16)
+// GLSL: layout(offset = 28)
+
+[numthreads(1, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ outputBuffer[dispatchThreadID.x] = v2;
+}
diff --git a/tests/hlsl/packoffset.slang.expected.txt b/tests/hlsl/packoffset.slang.expected.txt
new file mode 100644
index 000000000..56eb1d1d6
--- /dev/null
+++ b/tests/hlsl/packoffset.slang.expected.txt
@@ -0,0 +1,5 @@
+type: float
+8.000000
+0.000000
+0.000000
+0.000000
diff --git a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl b/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
index ec635a083..7f734bf75 100644
--- a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
+++ b/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
@@ -3,38 +3,29 @@
#extension GL_NV_ray_tracing_motion_blur : require
layout(row_major) uniform;
layout(row_major) buffer;
-struct ReflectionRay_0
-{
- float color_1;
-};
-
-layout(location = 0)
-rayPayloadEXT
-ReflectionRay_0 p_0;
-
-struct ShadowRay_0
-{
- float hitDistance_0;
-};
-
-layout(location = 1)
-rayPayloadEXT
-ShadowRay_0 p_1;
+#line 5 "tests/nv-extensions/nv-ray-tracing-motion-blur.slang"
layout(binding = 0)
uniform texture2D samplerPosition_0;
+
+#line 7
layout(binding = 2)
uniform sampler sampler_0;
+
+#line 6
layout(binding = 1)
uniform texture2D samplerNormal_0;
+
struct Light_0
{
vec4 position_0;
vec4 color_0;
};
+
+#line 14
struct Uniforms_0
{
Light_0 light_0;
@@ -43,11 +34,55 @@ struct Uniforms_0
mat4x4 model_0;
};
+
+#line 21
layout(binding = 3)
layout(std140) uniform _S1
{
- Uniforms_0 _data;
-} ubo_0;
+ Light_0 light_0;
+ vec4 viewPos_0;
+ mat4x4 view_0;
+ mat4x4 model_0;
+}ubo_0;
+
+#line 26
+layout(binding = 5)
+uniform accelerationStructureEXT as_0;
+
+
+#line 24
+layout(rgba32f)
+layout(binding = 4)
+uniform image2D outputImage_0;
+
+
+#line 33
+struct ReflectionRay_0
+{
+ float color_1;
+};
+
+
+#line 5218 "hlsl.meta.slang"
+layout(location = 0)
+rayPayloadEXT
+ReflectionRay_0 p_0;
+
+
+#line 28 "tests/nv-extensions/nv-ray-tracing-motion-blur.slang"
+struct ShadowRay_0
+{
+ float hitDistance_0;
+};
+
+
+#line 5286 "hlsl.meta.slang"
+layout(location = 1)
+rayPayloadEXT
+ShadowRay_0 p_1;
+
+
+#line 5079
struct RayDesc_0
{
vec3 Origin_0;
@@ -56,73 +91,116 @@ struct RayDesc_0
float TMax_0;
};
+
+#line 5243
void TraceMotionRay_0(accelerationStructureEXT AccelerationStructure_0, uint RayFlags_0, uint InstanceInclusionMask_0, uint RayContributionToHitGroupIndex_0, uint MultiplierForGeometryContributionToHitGroupIndex_0, uint MissShaderIndex_0, RayDesc_0 Ray_0, float CurrentTime_0, inout ShadowRay_0 Payload_0)
{
+
+#line 5288
p_1 = Payload_0;
traceRayMotionNV(AccelerationStructure_0, RayFlags_0, InstanceInclusionMask_0, RayContributionToHitGroupIndex_0, MultiplierForGeometryContributionToHitGroupIndex_0, MissShaderIndex_0, Ray_0.Origin_0, Ray_0.TMin_0, Ray_0.Direction_0, Ray_0.TMax_0, CurrentTime_0, (1));
+
+#line 5302
Payload_0 = p_1;
return;
}
-layout(binding = 5)
-uniform accelerationStructureEXT as_0;
+#line 3527
float saturate_0(float x_0)
{
return clamp(x_0, 0.0, 1.0);
}
+
+#line 5168
void TraceRay_0(accelerationStructureEXT AccelerationStructure_1, uint RayFlags_1, uint InstanceInclusionMask_1, uint RayContributionToHitGroupIndex_1, uint MultiplierForGeometryContributionToHitGroupIndex_1, uint MissShaderIndex_1, RayDesc_0 Ray_1, inout ReflectionRay_0 Payload_1)
{
+
+#line 5220
p_0 = Payload_1;
traceRayEXT(AccelerationStructure_1, RayFlags_1, InstanceInclusionMask_1, RayContributionToHitGroupIndex_1, MultiplierForGeometryContributionToHitGroupIndex_1, MissShaderIndex_1, Ray_1.Origin_0, Ray_1.TMin_0, Ray_1.Direction_0, Ray_1.TMax_0, (0));
+
+#line 5233
Payload_1 = p_0;
return;
}
-layout(rgba32f)
-layout(binding = 4)
-uniform image2D outputImage_0;
+#line 38 "tests/nv-extensions/nv-ray-tracing-motion-blur.slang"
void main()
{
uvec3 _S2 = ((gl_LaunchIDEXT));
+
+#line 40
ivec2 launchID_0 = ivec2(_S2.xy);
uvec3 _S3 = ((gl_LaunchSizeEXT));
+
+#line 41
ivec2 launchSize_0 = ivec2(_S3.xy);
+
vec2 inUV_0 = vec2((float(launchID_0.x) + 0.5) / float(launchSize_0.x), (float(launchID_0.y) + 0.5) / float(launchSize_0.y));
+
+#line 48
vec4 _S4 = (texture(sampler2D(samplerPosition_0,sampler_0), (inUV_0)));
+
+#line 48
vec3 P_0 = _S4.xyz;
vec4 _S5 = (texture(sampler2D(samplerNormal_0,sampler_0), (inUV_0)));
+
+#line 49
vec3 N_0 = _S5.xyz * 2.0 - 1.0;
- vec3 lightDelta_0 = ubo_0._data.light_0.position_0.xyz - P_0;
+
+ vec3 lightDelta_0 = ubo_0.light_0.position_0.xyz - P_0;
float lightDist_0 = length(lightDelta_0);
vec3 L_0 = normalize(lightDelta_0);
float _S6 = 1.0 / (lightDist_0 * lightDist_0);
+
RayDesc_0 ray_0;
ray_0.Origin_0 = P_0;
ray_0.TMin_0 = 0.00000099999999747524;
ray_0.Direction_0 = lightDelta_0;
ray_0.TMax_0 = lightDist_0;
+
ShadowRay_0 shadowRay_0;
shadowRay_0.hitDistance_0 = 0.0;
+
+
TraceMotionRay_0(as_0, 1U, 255U, 0U, 0U, 2U, ray_0, 1.0, shadowRay_0);
+
+#line 69
float atten_0;
+
+#line 87
if(shadowRay_0.hitDistance_0 < lightDist_0)
{
+
+#line 87
atten_0 = 0.0;
+
+#line 87
}
else
{
+
+#line 87
atten_0 = _S6;
+
+#line 87
}
- vec3 color_2 = ubo_0._data.light_0.color_0.xyz * saturate_0(dot(N_0, L_0)) * atten_0;
+
+#line 93
+ vec3 color_2 = ubo_0.light_0.color_0.xyz * saturate_0(dot(N_0, L_0)) * atten_0;
+
ReflectionRay_0 reflectionRay_0;
TraceRay_0(as_0, 1U, 255U, 0U, 0U, 2U, ray_0, reflectionRay_0);
+
+#line 117
imageStore((outputImage_0), ivec2((uvec2(launchID_0))), vec4(color_2 + reflectionRay_0.color_1, 1.0));
return;
}
+
diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
index 166d19537..bb605a14a 100644
--- a/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
+++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
@@ -3,6 +3,8 @@
#extension GL_EXT_ray_query : require
layout(row_major) uniform;
layout(row_major) buffer;
+
+#line 89 "tests/pipeline/ray-tracing/trace-ray-inline.slang"
struct SLANG_ParameterGroup_C_0
{
vec3 origin_0;
@@ -14,151 +16,276 @@ struct SLANG_ParameterGroup_C_0
uint shouldStopAtFirstHit_0;
};
+
+#line 89
layout(binding = 1)
layout(std140) uniform _S1
{
- SLANG_ParameterGroup_C_0 _data;
-} C_0;
+ vec3 origin_0;
+ float tMin_0;
+ vec3 direction_0;
+ float tMax_0;
+ uint rayFlags_0;
+ uint instanceMask_0;
+ uint shouldStopAtFirstHit_0;
+}C_0;
+
+#line 12
layout(binding = 0)
uniform accelerationStructureEXT myAccelerationStructure_0;
+
+#line 59
struct MyProceduralHitAttrs_0
{
int value_0;
};
+
+#line 81
bool myProceduralIntersection_0(inout float tHit_0, inout MyProceduralHitAttrs_0 hitAttrs_0)
{
return true;
}
+
+#line 26
struct MyRayPayload_0
{
int value_1;
};
+
+#line 69
bool myProceduralAnyHit_0(inout MyRayPayload_0 payload_0)
{
return true;
}
+
+#line 51
bool myTriangleAnyHit_0(inout MyRayPayload_0 payload_1)
{
return true;
}
+
+#line 40
void myTriangleClosestHit_0(inout MyRayPayload_0 payload_2)
{
payload_2.value_1 = 1;
return;
}
+
+#line 65
void myProceduralClosestHit_0(inout MyRayPayload_0 payload_3, MyProceduralHitAttrs_0 attrs_0)
{
payload_3.value_1 = attrs_0.value_0;
return;
}
+
+#line 33
void myMiss_0(inout MyRayPayload_0 payload_4)
{
payload_4.value_1 = 0;
return;
}
+
+#line 103
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main()
{
+
rayQueryEXT query_0;
+
MyRayPayload_0 payload_5;
+
+#line 110
payload_5.value_1 = -1;
- rayQueryInitializeEXT((query_0), (myAccelerationStructure_0), (C_0._data.rayFlags_0 | 512), (C_0._data.instanceMask_0), (C_0._data.origin_0), (C_0._data.tMin_0), (C_0._data.direction_0), (C_0._data.tMax_0));
+
+ rayQueryInitializeEXT((query_0), (myAccelerationStructure_0), (C_0.rayFlags_0 | 512), (C_0.instanceMask_0), (C_0.origin_0), (C_0.tMin_0), (C_0.direction_0), (C_0.tMax_0));
+
+#line 112
MyProceduralHitAttrs_0 committedProceduralAttrs_0;
+
+#line 112
for(;;)
{
+
+#line 121
bool _S2 = rayQueryProceedEXT(query_0);
+
+#line 121
if(!_S2)
{
+
+#line 121
break;
}
uint _S3 = (rayQueryGetIntersectionTypeEXT((query_0), false));
+
+#line 123
MyProceduralHitAttrs_0 committedProceduralAttrs_1;
+
+#line 123
switch(_S3)
{
case 1U:
{
MyProceduralHitAttrs_0 candidateProceduralAttrs_0;
+
+#line 127
candidateProceduralAttrs_0.value_0 = 0;
float tHit_1 = 0.0;
bool _S4 = myProceduralIntersection_0(tHit_1, candidateProceduralAttrs_0);
+
+#line 129
if(_S4)
{
bool _S5 = myProceduralAnyHit_0(payload_5);
+
+#line 131
if(_S5)
{
rayQueryGenerateIntersectionEXT(query_0, tHit_1);
MyProceduralHitAttrs_0 _S6 = candidateProceduralAttrs_0;
- if(C_0._data.shouldStopAtFirstHit_0 != 0U)
+ if(C_0.shouldStopAtFirstHit_0 != 0U)
{
+
+#line 136
rayQueryTerminateEXT(query_0);
+
+#line 135
}
+ else
+ {
+
+#line 135
+ }
+
+#line 135
committedProceduralAttrs_1 = _S6;
+
+#line 135
}
else
{
+
+#line 135
committedProceduralAttrs_1 = committedProceduralAttrs_0;
+
+#line 135
}
+
+#line 135
}
else
{
+
+#line 135
committedProceduralAttrs_1 = committedProceduralAttrs_0;
+
+#line 135
}
+
+#line 135
break;
}
case 0U:
{
+
+#line 144
bool _S7 = myTriangleAnyHit_0(payload_5);
+
+#line 144
if(_S7)
{
rayQueryConfirmIntersectionEXT(query_0);
- if(C_0._data.shouldStopAtFirstHit_0 != 0U)
+ if(C_0.shouldStopAtFirstHit_0 != 0U)
{
+
+#line 148
rayQueryTerminateEXT(query_0);
+
+#line 147
}
+ else
+ {
+
+#line 147
+ }
+
+#line 144
}
+ else
+ {
+
+#line 144
+ }
+
+#line 144
committedProceduralAttrs_1 = committedProceduralAttrs_0;
+
+#line 144
break;
}
default:
{
+
+#line 144
committedProceduralAttrs_1 = committedProceduralAttrs_0;
+
+#line 144
break;
}
}
+
+#line 119
committedProceduralAttrs_0 = committedProceduralAttrs_1;
+
+#line 119
}
+
+#line 158
uint _S8 = (rayQueryGetIntersectionTypeEXT((query_0), true));
+
+#line 158
switch(_S8)
{
case 1U:
{
+
+#line 161
myTriangleClosestHit_0(payload_5);
break;
}
case 2U:
{
+
+#line 165
myProceduralClosestHit_0(payload_5, committedProceduralAttrs_0);
break;
}
case 0U:
{
+
+#line 169
myMiss_0(payload_5);
break;
}
default:
{
+
+#line 170
break;
}
}
+
+#line 172
return;
}
+
diff --git a/tests/vkray/anyhit.slang.glsl b/tests/vkray/anyhit.slang.glsl
index 345dd6624..9d3584e1f 100644
--- a/tests/vkray/anyhit.slang.glsl
+++ b/tests/vkray/anyhit.slang.glsl
@@ -11,7 +11,7 @@ struct Params_0
layout(binding = 0)
layout(std140) uniform _S1
{
- Params_0 _data;
+ int mode_0;
} gParams_0;
layout(binding = 1)
@@ -34,7 +34,7 @@ rayPayloadInEXT ShadowRay_0 _S3;
void main()
{
- if(gParams_0._data.mode_0 != 0)
+ if(gParams_0.mode_0 != 0)
{
float val_0 = textureLod(
sampler2D(gParams_alphaMap_0, gParams_sampler_0),
diff --git a/tests/vkray/callable-caller.slang.glsl b/tests/vkray/callable-caller.slang.glsl
index 885c78dfa..a42e6eaf3 100644
--- a/tests/vkray/callable-caller.slang.glsl
+++ b/tests/vkray/callable-caller.slang.glsl
@@ -20,7 +20,7 @@ struct SLANG_ParameterGroup_C_0
layout(binding = 0)
layout(std140) uniform _S1
{
- SLANG_ParameterGroup_C_0 _data;
+ uint shaderIndex_0;
} C_0;
void CallShader_0(uint shaderIndex_1, inout MaterialPayload_0 payload_0)
{
@@ -42,7 +42,7 @@ void main()
vec2 _S3 = vec2(_S2.xy);
uvec3 _S4 = ((gl_LaunchSizeNV));
payload_1.uv_0 = _S3 / vec2(_S4.xy);
- CallShader_0(C_0._data.shaderIndex_0, payload_1);
+ CallShader_0(C_0.shaderIndex_0, payload_1);
uvec3 _S5 = ((gl_LaunchIDNV));
imageStore((gImage_0), ivec2((_S5.xy)), payload_1.albedo_0);
return;
diff --git a/tests/vkray/closesthit.slang.glsl b/tests/vkray/closesthit.slang.glsl
index b5daef909..6094b3a3d 100644
--- a/tests/vkray/closesthit.slang.glsl
+++ b/tests/vkray/closesthit.slang.glsl
@@ -23,7 +23,7 @@ struct SLANG_ParameterGroup_ShaderRecord_0
layout(shaderRecordNV)
buffer tmp_shaderrecord
{
- SLANG_ParameterGroup_ShaderRecord_0 _data;
+ uint shaderRecordID_0;
} ShaderRecord_0;
layout(std430, binding = 0) readonly buffer tmp_colors
@@ -59,7 +59,7 @@ void main()
uint tmp_add_1 = tmp_add_0 + tmp_primid;
uint tmp_hitkind = gl_HitKindNV;
- vec4 color_1 = colors_0._data[tmp_add_1 + tmp_hitkind + ShaderRecord_0._data.shaderRecordID_0];
+ vec4 color_1 = colors_0._data[tmp_add_1 + tmp_hitkind + ShaderRecord_0.shaderRecordID_0];
float tmp_hitt = gl_RayTmaxNV;
float tmp_tmin = gl_RayTminNV;
diff --git a/tests/vkray/entry-point-params.slang.glsl b/tests/vkray/entry-point-params.slang.glsl
index f4531ea84..00d2ba630 100644
--- a/tests/vkray/entry-point-params.slang.glsl
+++ b/tests/vkray/entry-point-params.slang.glsl
@@ -27,12 +27,12 @@ struct EntryPointParams_0
layout(shaderRecordEXT)
buffer _S2
{
- EntryPointParams_0 _data;
+ float value_0;
} _S3;
void main()
{
uvec3 _S4 = gl_LaunchIDEXT;
- buffer_0._data[_S4.x] = _S3._data.value_0;
+ buffer_0._data[_S4.x] = _S3.value_0;
return;
}
diff --git a/tests/vkray/intersection.slang.glsl b/tests/vkray/intersection.slang.glsl
index ac95432dd..1a08401af 100644
--- a/tests/vkray/intersection.slang.glsl
+++ b/tests/vkray/intersection.slang.glsl
@@ -17,7 +17,7 @@ struct SLANG_ParameterGroup_U_0
layout(binding = 0)
layout(std140) uniform _S1
{
- SLANG_ParameterGroup_U_0 _data;
+ Sphere_0 gSphere_0;
} U_0;
struct RayDesc_0
{
@@ -62,7 +62,7 @@ void main()
ray_1.TMax_0 = _S6;
float tHit_2;
SphereHitAttributes_0 attrs_1;
- bool _S7 = rayIntersectsSphere_0(ray_1, U_0._data.gSphere_0, tHit_2, attrs_1);
+ bool _S7 = rayIntersectsSphere_0(ray_1, U_0.gSphere_0, tHit_2, attrs_1);
if(_S7)
{
bool _S8 = ReportHit_0(tHit_2, uint(0), attrs_1);
diff --git a/tests/vkray/raygen.slang.glsl b/tests/vkray/raygen.slang.glsl
index 8bc9356a2..28bd5956b 100644
--- a/tests/vkray/raygen.slang.glsl
+++ b/tests/vkray/raygen.slang.glsl
@@ -45,7 +45,10 @@ struct Uniforms_0
layout(binding = 3)
layout(std140) uniform _S1
{
- Uniforms_0 _data;
+ Light_0 light_0;
+ vec4 viewPos_0;
+ mat4x4 view_0;
+ mat4x4 model_0;
} ubo_0;
struct RayDesc_0
{
@@ -99,7 +102,7 @@ void main()
vec4 _S10 = (texture(sampler2D(samplerNormal_0,sampler_0), (inUV_0)));
vec3 N_0 = _S10.xyz * 2.0 - 1.0;
- vec3 lightDelta_0 = ubo_0._data.light_0.position_0.xyz - P_0;
+ vec3 lightDelta_0 = ubo_0.light_0.position_0.xyz - P_0;
float lightDist_0 = length(lightDelta_0);
vec3 L_0 = normalize(lightDelta_0);
float _S11 = 1.0 / (lightDist_0 * lightDist_0);
@@ -121,7 +124,7 @@ void main()
{
atten_0 = _S11;
}
- vec3 color_2 = ubo_0._data.light_0.color_0.xyz * saturate_0(dot(N_0, L_0)) * atten_0;
+ vec3 color_2 = ubo_0.light_0.color_0.xyz * saturate_0(dot(N_0, L_0)) * atten_0;
ReflectionRay_0 reflectionRay_0;
TraceRay_1(as_0, 1U, 255U, 0U, 0U, 2U, ray_0, reflectionRay_0);