[SPIR-V] Allow SubpassInput without InputAttachmentIndex (#6240)

Vulkan allows SubpassInputs without an input attachment index specified,
so the error when it is missing has been removed and tests have been
updated.

As far as I can tell, there aren't earlier Vulkan or SPIR-V versions
where the presence of the the input attachment index was explicitly
required, so allowing it to be omitted in all cases.

Also added a test to verify that this fixes #2808 at the same time.

Fixes #6238, #2808
This commit is contained in:
Natalie Chouinard 2024-02-06 10:22:27 -05:00 коммит произвёл GitHub
Родитель 3c5f8ba749
Коммит 07a1c4ebfa
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 28 добавлений и 36 удалений

Просмотреть файл

@ -213,8 +213,10 @@ For example:
[[vk::input_attachment_index(i)]] SubpassInput input;
An ``vk::input_attachment_index`` of ``i`` selects the ith entry in the input
pass list. (See Vulkan API spec for more information.)
A ``vk::input_attachment_index`` of ``i`` selects the ith entry in the input
pass list. A subpass input without a ``vk::input_attachment_index`` will be
associated with the depth/stencil attachment. (See Vulkan API spec for more
information.)
Push constants
~~~~~~~~~~~~~~

Просмотреть файл

@ -1560,16 +1560,6 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
bool SpirvEmitter::validateVKAttributes(const NamedDecl *decl) {
bool success = true;
if (const auto *varDecl = dyn_cast<VarDecl>(decl)) {
const auto varType = varDecl->getType();
if ((isSubpassInput(varType) || isSubpassInputMS(varType)) &&
!varDecl->hasAttr<VKInputAttachmentIndexAttr>()) {
emitError("missing vk::input_attachment_index attribute",
varDecl->getLocation());
success = false;
}
}
if (decl->getAttr<VKInputAttachmentIndexAttr>()) {
if (!decl->isExternallyVisible()) {
emitError("SubpassInput(MS) must be externally visible",

Просмотреть файл

@ -4,6 +4,8 @@
// CHECK: OpDecorate %SI1 InputAttachmentIndex 1
// CHECK: OpDecorate %SI2 InputAttachmentIndex 2
// CHECK-NOT: OpDecorate %SI3 InputAttachmentIndex
// CHECK: OpDecorate %SI1 DescriptorSet 0
// CHECK: OpDecorate %SI1 Binding 5
@ -13,6 +15,9 @@
// CHECK: OpDecorate %SI0 DescriptorSet 0
// CHECK: OpDecorate %SI0 Binding 0
// CHECK: OpDecorate %SI3 DescriptorSet 0
// CHECK: OpDecorate %SI3 Binding 1
[[vk::input_attachment_index(0)]]
SubpassInput SI0;
@ -22,6 +27,8 @@ SubpassInput SI1;
[[vk::input_attachment_index(2), vk::binding(5, 3)]]
SubpassInput SI2;
SubpassInput SI3;
void main() {
}

Просмотреть файл

@ -22,24 +22,28 @@
// CHECK: %type_subpass_image_4 = OpTypeImage %int SubpassData 2 0 1 2 Unknown
// CHECK: %_ptr_UniformConstant_type_subpass_image_4 = OpTypePointer UniformConstant %type_subpass_image_4
// CHCK: %SI_f4 = OpVariable %_ptr_UniformConstant_type_subpass_image UniformConstant
// CHECK: %SI_f4 = OpVariable %_ptr_UniformConstant_type_subpass_image UniformConstant
[[vk::input_attachment_index(0)]] SubpassInput SI_f4;
// CHCK: %SI_i3 = OpVariable %_ptr_UniformConstant_type_subpass_image_0 UniformConstant
// CHECK: %SI_i3 = OpVariable %_ptr_UniformConstant_type_subpass_image_0 UniformConstant
[[vk::input_attachment_index(1)]] SubpassInput<int3> SI_i3;
// CHCK: %SI_u2 = OpVariable %_ptr_UniformConstant_type_subpass_image_1 UniformConstant
// CHECK: %SI_u2 = OpVariable %_ptr_UniformConstant_type_subpass_image_1 UniformConstant
[[vk::input_attachment_index(2)]] SubpassInput<uint2> SI_u2;
// CHCK: %SI_f1 = OpVariable %_ptr_UniformConstant_type_subpass_image UniformConstant
// CHECK: %SI_f1 = OpVariable %_ptr_UniformConstant_type_subpass_image UniformConstant
[[vk::input_attachment_index(3)]] SubpassInput<float> SI_f1;
// CHCK: %SIMS_u4 = OpVariable %_ptr_UniformConstant_type_subpass_image_2 UniformConstant
// CHECK: %SIMS_u4 = OpVariable %_ptr_UniformConstant_type_subpass_image_2 UniformConstant
[[vk::input_attachment_index(10)]] SubpassInputMS<uint4> SIMS_u4;
// CHCK: %SIMS_f3 = OpVariable %_ptr_UniformConstant_type_subpass_image_3 UniformConstant
// CHECK: %SIMS_f3 = OpVariable %_ptr_UniformConstant_type_subpass_image_3 UniformConstant
[[vk::input_attachment_index(11)]] SubpassInputMS<float3> SIMS_f3;
// CHCK: %SIMS_i2 = OpVariable %_ptr_UniformConstant_type_subpass_image_4 UniformConstant
// CHECK: %SIMS_i2 = OpVariable %_ptr_UniformConstant_type_subpass_image_4 UniformConstant
[[vk::input_attachment_index(12)]] SubpassInputMS<int2> SIMS_i2;
// CHCK: %SIMS_u1 = OpVariable %_ptr_UniformConstant_type_subpass_image_2 UniformConstant
// CHECK: %SIMS_u1 = OpVariable %_ptr_UniformConstant_type_subpass_image_2 UniformConstant
[[vk::input_attachment_index(13)]] SubpassInputMS<uint> SIMS_u1;
float4 ReadSourceFromTile(SubpassInput spi) {
return spi.SubpassLoad() ;
}
float4 main() : SV_Target {
// CHECK: [[img:%[0-9]+]] = OpLoad %type_subpass_image %SI_f4
// CHECK-NEXT: [[texel:%[0-9]+]] = OpImageRead %v4float [[img]] [[v2i00]] None
@ -60,6 +64,10 @@ float4 main() : SV_Target {
// CHECK-NEXT: [[val_1:%[0-9]+]] = OpCompositeExtract %float [[texel_2]] 0
// CHECK-NEXT: OpStore %v3 [[val_1]]
float v3 = SI_f1.SubpassLoad();
// CHECK: [[val_2:%[0-9]+]] = OpFunctionCall %v4float %ReadSourceFromTile %param_var_spi
// CHECK-NEXT: OpStore %v4 [[val_2]]
SubpassInput si = SI_f4;
float4 v4 = ReadSourceFromTile(si);
// CHECK: [[img_3:%[0-9]+]] = OpLoad %type_subpass_image_2 %SIMS_u4
// CHECK-NEXT: [[texel_3:%[0-9]+]] = OpImageRead %v4uint [[img_3]] [[v2i00]] Sample %int_1
@ -81,5 +89,5 @@ float4 main() : SV_Target {
// CHECK-NEXT: OpStore %v13 [[val_4]]
uint v13 = SIMS_u1.SubpassLoad(4);
return v0.x + v1.y + v2.x + v3 + v10.x + v11.y + v12.x + v13;
return v0.x + v1.y + v2.x + v3 + v4.x + v10.x + v11.y + v12.x + v13;
}

Просмотреть файл

@ -1,15 +0,0 @@
// RUN: not %dxc -T ps_6_0 -E main -fcgl %s -spirv 2>&1 | FileCheck %s
struct S {
float a;
float2 b;
float c;
};
SubpassInput SI0; // error
void main() {
}
// CHECK: :9:14: error: missing vk::input_attachment_index attribute