From 240aa243527eabcf87c30aabf9749396de47b1b2 Mon Sep 17 00:00:00 2001 From: Yong He Date: Thu, 16 Nov 2023 21:23:13 -0800 Subject: GLSL/SPIRV Fixes. (#3337) --- source/slang/slang-emit-spirv.cpp | 6 ++++++ source/slang/slang-ir-glsl-legalize.cpp | 2 +- source/slang/slang-ir-inst-defs.h | 1 + source/slang/slang-ir-insts.h | 5 +++++ source/slang/slang-ir-spirv-legalize.cpp | 16 ++++++++++---- .../slang/slang-ir-translate-glsl-global-var.cpp | 3 ++- tests/glsl/flat-in-float.slang | 24 +++++++++++++++++++++ tests/spirv/array-resource.slang | 25 ++++++++++++++++++++++ 8 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 tests/glsl/flat-in-float.slang create mode 100644 tests/spirv/array-resource.slang diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 4c802641d..869484ab9 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -1894,6 +1894,12 @@ struct SPIRVEmitContext emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), nullptr, varInst, SpvDecorationFlat); } } + + if (var->findDecorationImpl(kIROp_RequireSPIRVDescriptorIndexingExtensionDecoration)) + { + ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_descriptor_indexing")); + requireSPIRVCapability(SpvCapabilityRuntimeDescriptorArray); + } } void maybeEmitName(SpvInst* spvInst, IRInst* irInst) diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index 5ab85eca9..7bd4f77a3 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -1420,7 +1420,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( fieldBindingIndex, fieldBindingSpace, declarator, - field->getKey()); + field); if (fieldVal.flavor != ScalarizedVal::Flavor::none) { ScalarizedTupleValImpl::Element element; diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 88d398070..23f922b5b 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -848,6 +848,7 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(SemanticDecoration, semantic, 2, 0) INST(PackOffsetDecoration, packoffset, 2, 0) + INST(RequireSPIRVDescriptorIndexingExtensionDecoration, RequireSPIRVDescriptorIndexingExtensionDecoration, 0, 0) INST(SPIRVOpDecoration, spirvOpDecoration, 1, 0) /// Decorated function is marked for the forward-mode differentiation pass. diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 434f0305e..86a7e2e04 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -4237,6 +4237,11 @@ public: addDecoration(value, kIROp_SemanticDecoration, getStringValue(text), getIntValue(getIntType(), index)); } + void addRequireSPIRVDescriptorIndexingExtensionDecoration(IRInst* value) + { + addDecoration(value, kIROp_RequireSPIRVDescriptorIndexingExtensionDecoration); + } + void addTargetIntrinsicDecoration(IRInst* value, IRInst* caps, UnownedStringSlice const& definition, UnownedStringSlice const& predicate, IRInst* typeScrutinee) { typeScrutinee diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 7dbb02a71..2e9219c9d 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -464,7 +464,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase auto innerType = inst->getFullType(); - auto arrayType = as(inst->getDataType()); + auto arrayType = as(inst->getDataType()); IRInst* arraySize = nullptr; if (arrayType) { @@ -560,9 +560,17 @@ struct SPIRVLegalizationContext : public SourceEmitterBase } auto innerElementType = innerType; - if (arraySize) + if (arrayType) { - innerType = builder.getArrayType(innerType, arraySize); + Array arrayTypeArgs; + arrayTypeArgs.add(innerType); + if (arraySize) + arrayTypeArgs.add(arraySize); + innerType = (IRType*)builder.emitIntrinsicInst(builder.getTypeKind(), arrayType->getOp(), (UInt)arrayTypeArgs.getCount(), arrayTypeArgs.getBuffer()); + if (!arraySize) + { + builder.addRequireSPIRVDescriptorIndexingExtensionDecoration(inst); + } } // Make a pointer type of storageClass. @@ -577,7 +585,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase insertLoadAtLatestLocation(inst, use); }); } - else if (arraySize) + else if (arrayType) { traverseUses(inst, [&](IRUse* use) { diff --git a/source/slang/slang-ir-translate-glsl-global-var.cpp b/source/slang/slang-ir-translate-glsl-global-var.cpp index 41005e9d4..5d79cbe17 100644 --- a/source/slang/slang-ir-translate-glsl-global-var.cpp +++ b/source/slang/slang-ir-translate-glsl-global-var.cpp @@ -60,7 +60,7 @@ namespace Slang { builder.addNameHintDecoration(key, nameHint->getName()); } - builder.createStructField(inputStructType, key, inputType); + auto field = builder.createStructField(inputStructType, key, inputType); IRTypeLayout::Builder fieldTypeLayout(&builder); fieldTypeLayout.addResourceUsage(LayoutResourceKind::VaryingInput, LayoutSize(1)); IRVarLayout::Builder varLayoutBuilder(&builder, fieldTypeLayout.build()); @@ -86,6 +86,7 @@ namespace Slang inputVarIndex++; } inputStructTypeLayoutBuilder.addField(key, varLayoutBuilder.build()); + input->transferDecorationsTo(field); } auto paramTypeLayout = inputStructTypeLayoutBuilder.build(); IRVarLayout::Builder paramVarLayoutBuilder(&builder, paramTypeLayout); diff --git a/tests/glsl/flat-in-float.slang b/tests/glsl/flat-in-float.slang new file mode 100644 index 000000000..895e3c058 --- /dev/null +++ b/tests/glsl/flat-in-float.slang @@ -0,0 +1,24 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage fragment -entry main -allow-glsl -emit-spirv-directly +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage fragment -entry main -allow-glsl + +#version 310 es +precision highp float; +precision highp int; + +layout(location = 0) out mediump vec4 dEQP_FragColor; + +bool isOk(float a, float b) { return (a == b); } + +layout(location = 0) flat in float out0; +layout(binding = 0, std140) uniform Reference +{ + uint out0; +} ref; + +void main() +{ + bool RES = isOk(out0, ref.out0); + dEQP_FragColor = vec4(RES, RES, RES, 1.0); + // CHECK: OpDecorate {{.*}} Flat +} + diff --git a/tests/spirv/array-resource.slang b/tests/spirv/array-resource.slang new file mode 100644 index 000000000..b6edf9b27 --- /dev/null +++ b/tests/spirv/array-resource.slang @@ -0,0 +1,25 @@ +// array-resource.slang + +// Test direct SPIR-V emit on arrays of buffers. + +//TEST:SIMPLE(filecheck=CHECK):-target spirv -entry computeMain -stage compute -emit-spirv-directly +//TEST_INPUT:set resultBuffer = out ubuffer(data=[0 0 0 0], stride=4) + +// Note: we can't run this test at the moment because gfx doesn't support allocating shader objects with unsized arrays. +//TEST_DISABLED(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-vk -compute -output-using-type + +RWStructuredBuffer inputBuffers[]; + +RWStructuredBuffer resultBuffer; + +//TEST_INPUT: set inputBuffers = {ubuffer(data=[1 0 0 0], stride=4), ubuffer(data=[2 0 0 0], stride=4)} + +[numthreads(4,1,1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint threadId = dispatchThreadID.x; + resultBuffer[threadId] = inputBuffers[0][threadId] + inputBuffers[1][threadId]; + // CHECK: OpCapability RuntimeDescriptorArray + // CHECK: OpExtension "SPV_EXT_descriptor_indexing" + // BUFFER: 3 +} -- cgit v1.2.3