diff options
| -rw-r--r-- | slang.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 20 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-options.cpp | 3 | ||||
| -rw-r--r-- | tests/language-feature/no-hlsl-pack-constant-buffer-elements.slang | 22 |
6 files changed, 47 insertions, 3 deletions
@@ -932,6 +932,7 @@ extern "C" Heterogeneous, NoMangle, NoHLSLBinding, + NoHLSLPackConstantBufferElements, ValidateUniformity, AllowGLSL, diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 38708ae5e..25dff6083 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -2066,6 +2066,21 @@ bool CLikeSourceEmitter::isSingleElementConstantBuffer(IRInst* cbufferType) return true; } +bool CLikeSourceEmitter::shouldForceUnpackConstantBufferElements(IRInst* cbufferType) +{ + if (getTargetReq()->getTarget() != CodeGenTarget::HLSL) + return false; + if (!getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::NoHLSLPackConstantBufferElements)) + return false; + auto type = as<IRUniformParameterGroupType>(cbufferType); + if (!type) + 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; @@ -2195,8 +2210,9 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO { auto prec = getInfo(EmitOp::Postfix); needClose = maybeEmitParens(outerPrec, prec); - auto skipBase = isD3DTarget(getTargetReq()) && - hasExplicitConstantBufferOffset(ii->getBase()->getDataType()); + bool skipBase = (isD3DTarget(getTargetReq()) && + hasExplicitConstantBufferOffset(ii->getBase()->getDataType())) || + shouldForceUnpackConstantBufferElements(ii->getBase()->getDataType()); if (!skipBase) { auto base = ii->getBase(); diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h index ee7ce413a..64aa5f945 100644 --- a/source/slang/slang-emit-c-like.h +++ b/source/slang/slang-emit-c-like.h @@ -251,6 +251,7 @@ public: void emitType(IRType* type, NameLoc const& nameAndLoc); bool hasExplicitConstantBufferOffset(IRInst* cbufferType); bool isSingleElementConstantBuffer(IRInst* cbufferType); + bool shouldForceUnpackConstantBufferElements(IRInst* cbufferType); // // Expressions diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 9fcdef106..adca798e6 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -221,9 +221,10 @@ void HLSLSourceEmitter::_emitHLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor _emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain, varDecl); auto elementType = type->getElementType(); - if (hasExplicitConstantBufferOffset(type)) + if (shouldForceUnpackConstantBufferElements(type) || hasExplicitConstantBufferOffset(type)) { // If the user has provided any explicit `packoffset` modifiers, + // or the user has explicitly requested for cbuffer fields to be unpacked, // we have to unwrap the struct and emit the fields directly. emitStructDeclarationsBlock(as<IRStructType>(elementType), true); m_writer->emit("\n"); diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 13a11f10b..8a5c52e0e 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -520,6 +520,8 @@ void initCommandOptions(CommandOptions& options) { OptionKind::NoMangle, "-no-mangle", nullptr, "Do as little mangling of names as possible." }, { OptionKind::NoHLSLBinding, "-no-hlsl-binding", nullptr, "Do not include explicit parameter binding semantics in the output HLSL code," "except for parameters that has explicit bindings in the input source." }, + { OptionKind::NoHLSLPackConstantBufferElements, "-no-hlsl-pack-constant-buffer-elements", nullptr, + "Do not pack elements of constant buffers into structs in the output HLSL code." }, { OptionKind::ValidateUniformity, "-validate-uniformity", nullptr, "Perform uniformity validation analysis." }, { OptionKind::AllowGLSL, "-allow-glsl", nullptr, "Enable GLSL as an input language." }, }; @@ -1691,6 +1693,7 @@ SlangResult OptionsParser::_parse( case OptionKind::DumpAst: case OptionKind::IncompleteLibrary: case OptionKind::NoHLSLBinding: + case OptionKind::NoHLSLPackConstantBufferElements: linkage->m_optionSet.set(optionKind, true); break; break; case OptionKind::MatrixLayoutRow: diff --git a/tests/language-feature/no-hlsl-pack-constant-buffer-elements.slang b/tests/language-feature/no-hlsl-pack-constant-buffer-elements.slang new file mode 100644 index 000000000..84b574432 --- /dev/null +++ b/tests/language-feature/no-hlsl-pack-constant-buffer-elements.slang @@ -0,0 +1,22 @@ +//TEST:SIMPLE(filecheck=CHECK):-target hlsl -entry main -profile cs_6_0 -no-hlsl-pack-constant-buffer-elements +//TEST:SIMPLE(filecheck=DXIL): -target dxil -entry main -profile cs_6_0 -no-hlsl-pack-constant-buffer-elements + +// DXIL: define void @main() + +// Test that -no-hlsl-pack-constant-buffer-elements prevents packing of elements in the output HLSL code. + +// CHECK-DAG: cbuffer {{.*}} : +cbuffer MyCB +{ + float member0; + float member1; +} + +RWStructuredBuffer<float> MyBuffer; + +// CHECK-DAG: {{.*}} = member0{{.*}} + member1{{.*}}; +[numthreads(1,1,1)] +void main() +{ + MyBuffer[0] = member0 + member1; +} |
