summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-08-10 14:58:41 -0700
committerGitHub <noreply@github.com>2023-08-10 14:58:41 -0700
commit38b0af3537f5d8412f0d69e39e38c5603ff62c15 (patch)
tree5892b0b2427f0de0057259949e03105ec766143a
parent60ebadab1ec269c7017148a028307a9b5f32b1d4 (diff)
Add support for ConstBufferPointer on Vulkan. (#3089)
* Add support for `ConstBufferPointer` on Vulkan. * Add spv compilation test. * Fix. * Fix code review issues. --------- Co-authored-by: Yong He <yhe@nvidia.com>
-rw-r--r--source/slang/hlsl.meta.slang15
-rw-r--r--source/slang/slang-ast-type.h6
-rw-r--r--source/slang/slang-emit-c-like.cpp14
-rw-r--r--source/slang/slang-emit-glsl.cpp35
-rw-r--r--source/slang/slang-emit-glsl.h2
-rw-r--r--source/slang/slang-ir-inst-defs.h1
-rw-r--r--source/slang/slang-ir.h6
-rw-r--r--source/slang/slang-type-layout.cpp2
-rw-r--r--tests/hlsl-intrinsic/const-buffer-pointer.slang39
9 files changed, 118 insertions, 2 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 56ad32326..434a8245a 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -7775,3 +7775,18 @@ ${{{{
${{{{
}
}}}}
+
+// Buffer Pointer
+
+__generic<T, let Alignment : int = 16>
+__intrinsic_type($(kIROp_HLSLConstBufferPointerType))
+__glsl_extension(GL_EXT_buffer_reference)
+__magic_type(ConstBufferPointerType)
+struct ConstBufferPointer
+{
+ __glsl_version(450)
+ __glsl_extension(GL_EXT_buffer_reference)
+ __target_intrinsic(glsl, "$0._data")
+ [__NoSideEffect]
+ T get();
+}
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h
index 8948f742c..f3dc975a3 100644
--- a/source/slang/slang-ast-type.h
+++ b/source/slang/slang-ast-type.h
@@ -519,6 +519,12 @@ class PtrType : public PtrTypeBase
SLANG_AST_CLASS(PtrType)
};
+// A GPU pointer type that for general readonly memory access.
+class ConstBufferPointerType : public PtrTypeBase
+{
+ SLANG_AST_CLASS(ConstBufferPointerType)
+};
+
/// A pointer-like type used to represent a parameter "direction"
class ParamDirectionType : public PtrTypeBase
{
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index e2faba808..0cc3a196b 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -966,6 +966,19 @@ String CLikeSourceEmitter::generateName(IRInst* inst)
return linkageDecoration->getMangledName();
}
+ switch (inst->getOp())
+ {
+ case kIROp_HLSLConstBufferPointerType:
+ {
+ StringBuilder sb;
+ sb << "BufferPointer_";
+ sb << getName(inst->getOperand(0));
+ sb << "_" << Int32(getID(inst));
+ return sb.produceString();
+ }
+ default:
+ break;
+ }
// Otherwise fall back to a construct temporary name
// for the instruction.
StringBuilder sb;
@@ -3743,7 +3756,6 @@ void CLikeSourceEmitter::emitGlobalInstImpl(IRInst* inst)
case kIROp_InterfaceType:
emitInterface(cast<IRInterfaceType>(inst));
break;
-
case kIROp_WitnessTable:
emitWitnessTable(cast<IRWitnessTable>(inst));
break;
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 321f41d54..22a0c323b 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -1617,6 +1617,39 @@ bool GLSLSourceEmitter::_tryEmitBitBinOp(IRInst* inst, const EmitOpInfo& bitOp,
}
+void GLSLSourceEmitter::emitBufferPointerTypeDefinition(IRInst* ptrType)
+{
+ _requireGLSLExtension(UnownedStringSlice("GL_EXT_buffer_reference"));
+
+ auto constPtrType = as<IRHLSLConstBufferPointerType>(ptrType);
+ auto ptrTypeName = getName(ptrType);
+ auto alignment = getIntVal(constPtrType->getBaseAlignment());
+ m_writer->emit("layout(buffer_reference, std430, buffer_reference_align = ");
+ m_writer->emitInt64(alignment);
+ m_writer->emit(") readonly buffer ");
+ m_writer->emit(ptrTypeName);
+ m_writer->emit("\n");
+ m_writer->emit("{\n");
+ m_writer->indent();
+ emitType((IRType*)constPtrType->getValueType(), "_data");
+ m_writer->emit(";\n");
+ m_writer->dedent();
+ m_writer->emit("};\n");
+}
+
+void GLSLSourceEmitter::emitGlobalInstImpl(IRInst* inst)
+{
+ switch (inst->getOp())
+ {
+ case kIROp_HLSLConstBufferPointerType:
+ emitBufferPointerTypeDefinition(inst);
+ break;
+ default:
+ Super::emitGlobalInstImpl(inst);
+ break;
+ }
+}
+
bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec)
{
switch (inst->getOp())
@@ -2228,6 +2261,7 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type)
return;
}
case kIROp_StructType:
+ case kIROp_HLSLConstBufferPointerType:
m_writer->emit(getName(type));
return;
@@ -2629,3 +2663,4 @@ void GLSLSourceEmitter::emitMatrixLayoutModifiersImpl(IRVarLayout* layout)
} // namespace Slang
+
diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h
index c0f3336f0..d0cabfa94 100644
--- a/source/slang/slang-emit-glsl.h
+++ b/source/slang/slang-emit-glsl.h
@@ -48,6 +48,8 @@ protected:
virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE;
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
+ virtual void emitGlobalInstImpl(IRInst* inst) override;
+ void emitBufferPointerTypeDefinition(IRInst* ptrType);
virtual void emitSimpleValueImpl(IRInst* inst) SLANG_OVERRIDE;
virtual void emitLoopControlDecorationImpl(IRLoopControlDecoration* decl) SLANG_OVERRIDE;
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index c26d5fe53..062da75e8 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -119,6 +119,7 @@ INST(Nop, nop, 0, 0)
INST(OutType, Out, 1, HOISTABLE)
INST(InOutType, InOut, 1, HOISTABLE)
INST_RANGE(OutTypeBase, OutType, InOutType)
+ INST(HLSLConstBufferPointerType, ConstBufferPointerType, 2, HOISTABLE)
INST_RANGE(PtrTypeBase, PtrType, InOutType)
// A ComPtr<T> type is treated as a opaque type that represents a reference-counted handle to a COM object.
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 3cd8e9126..cdce11bbb 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1641,6 +1641,12 @@ struct IRRTTIPointerType : IRRawPointerTypeBase
IR_LEAF_ISA(RTTIPointerType)
};
+struct IRHLSLConstBufferPointerType : IRPtrTypeBase
+{
+ IR_LEAF_ISA(HLSLConstBufferPointerType)
+ IRInst* getBaseAlignment() { return getOperand(1); }
+};
+
struct IRGlobalHashedStringLiterals : IRInst
{
IR_LEAF_ISA(GlobalHashedStringLiterals)
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index f5e14366d..d075b12e2 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -3928,7 +3928,7 @@ static TypeLayoutResult _createTypeLayout(
{
return createArrayLikeTypeLayout(context, arrayType, arrayType->getElementType(), arrayType->getElementCount());
}
- else if (auto ptrType = as<PtrType>(type))
+ else if (auto ptrType = as<PtrTypeBase>(type))
{
RefPtr<PointerTypeLayout> ptrLayout = new PointerTypeLayout();
diff --git a/tests/hlsl-intrinsic/const-buffer-pointer.slang b/tests/hlsl-intrinsic/const-buffer-pointer.slang
new file mode 100644
index 000000000..33b538a60
--- /dev/null
+++ b/tests/hlsl-intrinsic/const-buffer-pointer.slang
@@ -0,0 +1,39 @@
+//TEST:SIMPLE(filecheck=CHECK):-target glsl -profile glsl_450 -entry main -stage compute
+//TEST:SIMPLE(filecheck=SPV):-target spirv -profile glsl_450 -entry main -stage compute
+
+// SPV: EntryPoint GLCompute {{.*}} "main" {{.*}}
+
+struct MyStruct
+{
+ float4 position;
+ float4x4 transform;
+}
+
+// CHECK: layout(buffer_reference, std430, buffer_reference_align = 16) readonly buffer BufferPointer_MyStruct
+// CHECK-NEXT: {
+// CHECK-NEXT: MyStruct{{.*}} _data;
+// CHECK-NEXT: }
+
+// CHECK: struct Globals
+// CHECK-NEXT: {
+// CHECK-NEXT: BufferPointer_MyStruct{{.*}} pStruct
+// CHECK-NEXT: }
+
+// CHECK: void main
+// CHECK: MyStruct{{.*}} s{{.*}} = ((gGlobals{{.*}}.pStruct{{.*}})._data);
+
+struct Globals
+{
+ ConstBufferPointer<MyStruct> pStruct;
+}
+
+ConstantBuffer<Globals> gGlobals;
+
+RWStructuredBuffer<uint> outputBuffer;
+
+[numthreads(1,1,1)]
+void main(int3 tid: SV_DispatchThreadID)
+{
+ MyStruct s = gGlobals.pStruct.get();
+ outputBuffer[tid.x] = uint(s.position.x);
+} \ No newline at end of file