summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-spirv.cpp
diff options
context:
space:
mode:
authorLujin Wang <143145775+lujinwangnv@users.noreply.github.com>2025-09-26 16:07:13 -0700
committerGitHub <noreply@github.com>2025-09-26 23:07:13 +0000
commit99de1a6203f676955f80de8c93c0f56c91d4ca96 (patch)
tree2db039fb597a55cf455747eda31d35f578ceda0c /source/slang/slang-emit-spirv.cpp
parente9f74ebfa83cd6aca39d7e3da2801cd47935bd1a (diff)
Add SPV_NV_bindless_texture support (#8534)
Treat DescriptorHandle as uint64_t instead of uint2. Implement target-specific SPIR-V emission with the bindless texture support. For OpImageTexelPointer, Image must have a type of OpTypePointer with Type OpTypeImage. Fix the issue by using [constref] in __subscript. Add a test coverage for various texture/sampler handle types. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-emit-spirv.cpp')
-rw-r--r--source/slang/slang-emit-spirv.cpp87
1 files changed, 85 insertions, 2 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 18c54587a..7b1bd66d8 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1500,12 +1500,30 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
m_addressingMode,
m_memoryModel);
+ // Emit OpSamplerImageAddressingModeNV if bindless texture capability is enabled
+ auto targetCaps = m_targetProgram->getTargetReq()->getTargetCaps();
+
+ if (targetCaps.implies(CapabilityAtom::spvBindlessTextureNV))
+ {
+ requireSPIRVCapability((SpvCapability)SpvCapabilityBindlessTextureNV);
+ requireSPIRVCapability(SpvCapabilityInt64); // Required for 64-bit addressing mode
+ ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_bindless_texture"));
+
+ emitInstCustomOperandFunc(
+ getSection(SpvLogicalSectionID::MemoryModel),
+ nullptr,
+ SpvOpSamplerImageAddressingModeNV,
+ [&]()
+ {
+ emitOperand(SpvWord(64)); // 64-bit addressing mode
+ });
+ }
+
if (m_memoryModel == SpvMemoryModelVulkan)
{
requireSPIRVCapability(SpvCapabilityVulkanMemoryModel);
ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_vulkan_memory_model"));
- auto targetCaps = m_targetProgram->getTargetReq()->getTargetCaps();
if (targetCaps.implies(CapabilityAtom::spvVulkanMemoryModelDeviceScopeKHR))
{
requireSPIRVCapability(SpvCapabilityVulkanMemoryModelDeviceScope);
@@ -2129,7 +2147,25 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
{
IRBuilder builder(inst);
builder.setInsertBefore(inst);
- return emitOpTypeVector(inst, builder.getUIntType(), SpvLiteralInteger::from32(2));
+ auto targetCaps = m_targetProgram->getTargetReq()->getTargetCaps();
+
+ if (targetCaps.implies(CapabilityAtom::spvBindlessTextureNV))
+ {
+ // For spvBindlessTextureNV, DescriptorHandleType should be a uint64_t
+ // (OpTypeInt 64 0)
+ return emitOpTypeInt(
+ inst,
+ SpvLiteralInteger::from32(64),
+ SpvLiteralInteger::from32(0));
+ }
+ else
+ {
+ // For other targets, use uint2 (OpTypeVector of 2 uint32)
+ return emitOpTypeVector(
+ inst,
+ builder.getUIntType(),
+ SpvLiteralInteger::from32(2));
+ }
}
case kIROp_SubpassInputType:
return ensureSubpassInputType(inst, cast<IRSubpassInputType>(inst));
@@ -4154,12 +4190,59 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_CastDescriptorHandleToUInt2:
case kIROp_CastUInt2ToDescriptorHandle:
case kIROp_GlobalValueRef:
+ case kIROp_CastUInt64ToDescriptorHandle:
+ case kIROp_CastDescriptorHandleToUInt64:
{
auto inner = ensureInst(inst->getOperand(0));
registerInst(inst, inner);
result = inner;
break;
}
+ case kIROp_CastDescriptorHandleToResource:
+ // Convert DescriptorHandle (uint64_t handle) to appropriate resource type
+ {
+ auto targetCaps = m_targetProgram->getTargetReq()->getTargetCaps();
+
+ if (targetCaps.implies(CapabilityAtom::spvBindlessTextureNV))
+ {
+ requireSPIRVCapability((SpvCapability)SpvCapabilityBindlessTextureNV);
+ ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_bindless_texture"));
+
+ auto operand = ensureInst(inst->getOperand(0));
+ SpvOp conversionOp = SpvOpConvertUToSampledImageNV;
+ IRType* resultType = inst->getDataType();
+
+ switch (resultType->getOp())
+ {
+ case kIROp_TextureType:
+ conversionOp = SpvOpConvertUToSampledImageNV;
+ result = emitInst(
+ parent,
+ inst,
+ conversionOp,
+ inst->getDataType(),
+ kResultID,
+ operand);
+ break;
+ case kIROp_SamplerStateType:
+ conversionOp = SpvOpConvertUToSamplerNV;
+ result = emitInst(
+ parent,
+ inst,
+ conversionOp,
+ inst->getDataType(),
+ kResultID,
+ operand);
+ break;
+ default:
+ // Unsupported result type for descriptor-to-resource conversion
+ SLANG_UNEXPECTED(
+ "Unsupported result type for CastDescriptorHandleToResource");
+ break;
+ }
+ }
+ break;
+ }
case kIROp_GetVulkanRayTracingPayloadLocation:
{
IRInst* location = getVulkanPayloadLocation(inst->getOperand(0));