Skip to content

Commit 4485cf3

Browse files
authored
Update SPIRV-Tools and fix new validation errors. (#6511)
* Update SPIRV-Tools and fix new validation errors. * Implement pointers for glsl target. * Reworked packStorage/unpackStorage code gen to operate on pointers rather than values.
1 parent 55dd2de commit 4485cf3

25 files changed

+686
-410
lines changed

source/slang/hlsl.meta.slang

+11-65
Original file line numberDiff line numberDiff line change
@@ -21609,90 +21609,36 @@ extension uint64_t
2160921609
}
2161021610
}
2161121611

21612-
__generic<T, let Alignment : int = 16>
21613-
__intrinsic_type($(kIROp_HLSLConstBufferPointerType))
21614-
__glsl_extension(GL_EXT_buffer_reference)
21615-
__magic_type(ConstBufferPointerType)
21616-
[require(glsl_spirv, bufferreference)]
21617-
struct ConstBufferPointer
21612+
struct ConstBufferPointer<T, int alignment = 16>
2161821613
{
21619-
__glsl_version(450)
21620-
__glsl_extension(GL_EXT_buffer_reference)
21621-
[__NoSideEffect]
21622-
T get()
21623-
{
21624-
__target_switch
21625-
{
21626-
case glsl:
21627-
__intrinsic_asm "$0._data";
21628-
case spirv:
21629-
return spirv_asm {
21630-
result:$$T = OpLoad $this Aligned !Alignment;
21631-
};
21632-
}
21633-
}
21634-
21614+
T *_ptr;
2163521615

21616+
[ForceInline] T get() { return loadAligned<alignment>(_ptr); }
2163621617

2163721618
__subscript(int index) -> T
2163821619
{
2163921620
[ForceInline]
21640-
get {return ConstBufferPointer<T>.fromUInt(toUInt() + __naturalStrideOf<T>() * index).get(); }
21621+
get { return _ptr[index]; }
2164121622
}
2164221623

21643-
__glsl_version(450)
21644-
__glsl_extension(GL_EXT_shader_explicit_arithmetic_types_int64)
21645-
__glsl_extension(GL_EXT_buffer_reference)
21646-
[require(glsl_spirv, bufferreference_int64)]
21624+
[ForceInline] T* getPtr() { return _ptr; }
21625+
21626+
[ForceInline]
2164721627
static ConstBufferPointer<T> fromUInt(uint64_t val)
2164821628
{
21649-
__target_switch
21650-
{
21651-
case glsl:
21652-
__intrinsic_asm "$TR($0)";
21653-
case spirv:
21654-
return spirv_asm {
21655-
result:$$ConstBufferPointer<T> = OpConvertUToPtr $val;
21656-
};
21657-
}
21629+
return {(T*)val};
2165821630
}
2165921631

21660-
__glsl_version(450)
21661-
__glsl_extension(GL_EXT_shader_explicit_arithmetic_types_int64)
21662-
__glsl_extension(GL_EXT_buffer_reference)
21663-
[require(glsl_spirv, bufferreference_int64)]
21632+
[ForceInline]
2166421633
uint64_t toUInt()
2166521634
{
21666-
__target_switch
21667-
{
21668-
case glsl:
21669-
__intrinsic_asm "uint64_t($0)";
21670-
case spirv:
21671-
return spirv_asm {
21672-
result:$$uint64_t = OpConvertPtrToU $this;
21673-
};
21674-
}
21635+
return (uint64_t)_ptr;
2167521636
}
2167621637

21677-
__glsl_version(450)
21678-
__glsl_extension(GL_EXT_shader_explicit_arithmetic_types_int64)
21679-
__glsl_extension(GL_EXT_buffer_reference)
21680-
[__NoSideEffect]
2168121638
[ForceInline]
21682-
[require(glsl_spirv, bufferreference_int64)]
2168321639
bool isValid()
2168421640
{
21685-
__target_switch
21686-
{
21687-
case glsl:
21688-
__intrinsic_asm "(uint64_t($0) != 0)";
21689-
case spirv:
21690-
uint64_t zero = 0ULL;
21691-
return spirv_asm {
21692-
%ptrval:$$uint64_t = OpConvertPtrToU $this;
21693-
result:$$bool = OpINotEqual %ptrval $zero;
21694-
};
21695-
}
21641+
return _ptr != nullptr;
2169621642
}
2169721643
}
2169821644

source/slang/slang-ast-type.h

-7
Original file line numberDiff line numberDiff line change
@@ -632,13 +632,6 @@ class PtrType : public PtrTypeBase
632632
void _toTextOverride(StringBuilder& out);
633633
};
634634

635-
// A GPU pointer type into global memory.
636-
637-
class ConstBufferPointerType : public PtrTypeBase
638-
{
639-
SLANG_AST_CLASS(ConstBufferPointerType)
640-
};
641-
642635
/// A pointer-like type used to represent a parameter "direction"
643636
class ParamDirectionType : public PtrTypeBase
644637
{

source/slang/slang-emit-c-like.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -1236,19 +1236,18 @@ String CLikeSourceEmitter::generateName(IRInst* inst)
12361236
return linkageDecoration->getMangledName();
12371237
}
12381238

1239-
switch (inst->getOp())
1239+
if (auto ptrType = as<IRPtrType>(inst))
12401240
{
1241-
case kIROp_HLSLConstBufferPointerType:
1241+
if (ptrType->getAddressSpace() == AddressSpace::UserPointer)
12421242
{
12431243
StringBuilder sb;
12441244
sb << "BufferPointer_";
12451245
sb << getName(inst->getOperand(0));
12461246
sb << "_" << Int32(getID(inst));
12471247
return sb.produceString();
12481248
}
1249-
default:
1250-
break;
12511249
}
1250+
12521251
// Otherwise fall back to a construct temporary name
12531252
// for the instruction.
12541253
StringBuilder sb;

source/slang/slang-emit-glsl.cpp

+109-7
Original file line numberDiff line numberDiff line change
@@ -2036,21 +2036,30 @@ bool GLSLSourceEmitter::_tryEmitBitBinOp(
20362036
return true;
20372037
}
20382038

2039-
void GLSLSourceEmitter::emitBufferPointerTypeDefinition(IRInst* ptrType)
2039+
void GLSLSourceEmitter::emitBufferPointerTypeDefinition(IRInst* type)
20402040
{
2041+
auto ptrType = as<IRPtrType>(type);
2042+
if (!ptrType)
2043+
return;
2044+
if (ptrType->getAddressSpace() != AddressSpace::UserPointer)
2045+
return;
20412046
_requireGLSLExtension(UnownedStringSlice("GL_EXT_buffer_reference"));
20422047

2043-
auto constPtrType = as<IRHLSLConstBufferPointerType>(ptrType);
20442048
auto ptrTypeName = getName(ptrType);
2045-
auto alignment = getIntVal(constPtrType->getBaseAlignment());
2049+
IRSizeAndAlignment sizeAlignment;
2050+
getNaturalSizeAndAlignment(
2051+
m_codeGenContext->getTargetProgram()->getOptionSet(),
2052+
ptrType->getValueType(),
2053+
&sizeAlignment);
2054+
auto alignment = sizeAlignment.alignment;
20462055
m_writer->emit("layout(buffer_reference, std430, buffer_reference_align = ");
20472056
m_writer->emitInt64(alignment);
20482057
m_writer->emit(") readonly buffer ");
20492058
m_writer->emit(ptrTypeName);
20502059
m_writer->emit("\n");
20512060
m_writer->emit("{\n");
20522061
m_writer->indent();
2053-
emitType((IRType*)constPtrType->getValueType(), "_data");
2062+
emitType((IRType*)ptrType->getValueType(), "_data");
20542063
m_writer->emit(";\n");
20552064
m_writer->dedent();
20562065
m_writer->emit("};\n");
@@ -2079,7 +2088,7 @@ void GLSLSourceEmitter::emitGlobalInstImpl(IRInst* inst)
20792088
{
20802089
switch (inst->getOp())
20812090
{
2082-
case kIROp_HLSLConstBufferPointerType:
2091+
case kIROp_PtrType:
20832092
emitBufferPointerTypeDefinition(inst);
20842093
break;
20852094
// No need to use structs which are just taking part in a SSBO declaration
@@ -2102,6 +2111,43 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
21022111
m_writer->emit("barrier();\n");
21032112
return true;
21042113
}
2114+
case kIROp_Load:
2115+
{
2116+
auto addr = inst->getOperand(0);
2117+
auto ptrType = as<IRPtrType>(addr->getDataType());
2118+
if (!ptrType)
2119+
return false;
2120+
if (ptrType->getAddressSpace() == AddressSpace::UserPointer)
2121+
{
2122+
auto prec = getInfo(EmitOp::Postfix);
2123+
EmitOpInfo outerPrec = inOuterPrec;
2124+
bool needClose = maybeEmitParens(outerPrec, prec);
2125+
emitOperand(inst->getOperand(0), prec);
2126+
m_writer->emit("._data");
2127+
maybeCloseParens(needClose);
2128+
return true;
2129+
}
2130+
return false;
2131+
}
2132+
case kIROp_FieldAddress:
2133+
{
2134+
auto addr = inst->getOperand(0);
2135+
auto ptrType = as<IRPtrType>(addr->getDataType());
2136+
if (!ptrType)
2137+
return false;
2138+
if (ptrType->getAddressSpace() == AddressSpace::UserPointer)
2139+
{
2140+
auto prec = getInfo(EmitOp::Postfix);
2141+
EmitOpInfo outerPrec = inOuterPrec;
2142+
bool needClose = maybeEmitParens(outerPrec, prec);
2143+
emitOperand(inst->getOperand(0), prec);
2144+
m_writer->emit("._data.");
2145+
emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
2146+
maybeCloseParens(needClose);
2147+
return true;
2148+
}
2149+
return false;
2150+
}
21052151
case kIROp_MakeVectorFromScalar:
21062152
case kIROp_MatrixReshape:
21072153
{
@@ -2372,10 +2418,57 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
23722418

23732419
return true;
23742420
}
2421+
if (as<IRPtrType>(left->getDataType()) || as<IRPtrType>(right->getDataType()))
2422+
{
2423+
_requireGLSLExtension(
2424+
UnownedStringSlice("GL_EXT_shader_explicit_arithmetic_types_int64"));
23752425

2426+
// For pointers we need to cast to uint before comparing
2427+
auto getOperatorString = [](IROp op) -> const char*
2428+
{
2429+
switch (op)
2430+
{
2431+
case kIROp_Eql:
2432+
return "==";
2433+
case kIROp_Neq:
2434+
return "!=";
2435+
case kIROp_Greater:
2436+
return ">";
2437+
case kIROp_Less:
2438+
return "<";
2439+
case kIROp_Geq:
2440+
return ">=";
2441+
case kIROp_Leq:
2442+
return "<=";
2443+
default:
2444+
return nullptr;
2445+
}
2446+
};
2447+
EmitOpInfo outerPrec = inOuterPrec;
2448+
auto prec = getInfo(EmitOp::General);
2449+
bool needClose = maybeEmitParens(outerPrec, prec);
2450+
2451+
m_writer->emit("uint64_t(");
2452+
emitOperand(left, getInfo(EmitOp::General));
2453+
m_writer->emit(")");
2454+
m_writer->emit(" ");
2455+
m_writer->emit(getOperatorString(inst->getOp()));
2456+
m_writer->emit(" ");
2457+
m_writer->emit("uint64_t(");
2458+
emitOperand(right, getInfo(EmitOp::General));
2459+
m_writer->emit(")");
2460+
2461+
maybeCloseParens(needClose);
2462+
return true;
2463+
}
23762464
// Use the default
23772465
break;
23782466
}
2467+
case kIROp_GetOffsetPtr:
2468+
{
2469+
_requireGLSLExtension(UnownedStringSlice("GL_EXT_buffer_reference2"));
2470+
return false;
2471+
}
23792472
case kIROp_FRem:
23802473
{
23812474
IRInst* left = inst->getOperand(0);
@@ -2560,6 +2653,16 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
25602653
m_writer->emit(")");
25612654
return true;
25622655
}
2656+
case kIROp_PtrLit:
2657+
{
2658+
auto ptrType = as<IRPtrType>(inst->getDataType());
2659+
if (ptrType)
2660+
{
2661+
m_writer->emit("0");
2662+
return true;
2663+
}
2664+
break;
2665+
}
25632666
default:
25642667
break;
25652668
}
@@ -3204,10 +3307,9 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type)
32043307
return;
32053308
}
32063309
case kIROp_StructType:
3207-
case kIROp_HLSLConstBufferPointerType:
3310+
case kIROp_PtrType:
32083311
m_writer->emit(getName(type));
32093312
return;
3210-
32113313
case kIROp_VectorType:
32123314
{
32133315
auto vecType = (IRVectorType*)type;

source/slang/slang-emit-spirv-ops.h

+14
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,20 @@ SpvInst* emitOpBitcast(
14091409
return emitInst(parent, inst, SpvOpBitcast, idResultType, kResultID, operand);
14101410
}
14111411

1412+
// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpCopyLogical
1413+
template<typename T1, typename T2>
1414+
SpvInst* emitOpCopyLogical(
1415+
SpvInstParent* parent,
1416+
IRInst* inst,
1417+
const T1& idResultType,
1418+
const T2& operand)
1419+
{
1420+
static_assert(isSingular<T1>);
1421+
static_assert(isSingular<T2>);
1422+
return emitInst(parent, inst, SpvOpCopyLogical, idResultType, kResultID, operand);
1423+
}
1424+
1425+
14121426
// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpSNegate
14131427
template<typename T1, typename T2>
14141428
SpvInst* emitOpSNegate(

0 commit comments

Comments
 (0)