blob: 60cf14231cdbf793f1634a6ab4edbea481f5a3ca [file]
/*
* Copyright (c) 2025 NVIDIA Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include "../framework/shader_object_helper.h"
class NegativeShader64BitIndexing : public VkLayerTest {};
TEST_F(NegativeShader64BitIndexing, Length64) {
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredFeature(vkt::Feature::shader64BitIndexing);
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
const char* cs_source = R"glsl(
#version 450
#extension GL_EXT_shader_64bit_indexing : enable
layout(set = 0, binding = 0) readonly buffer B { float x[]; } b;
void main(){ b.x.length64(); }
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};
m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpArrayLength-11807");
pipe.CreateComputePipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeShader64BitIndexing, ShaderObjectLength64) {
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredFeature(vkt::Feature::shader64BitIndexing);
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredFeature(vkt::Feature::dynamicRendering);
AddRequiredFeature(vkt::Feature::shaderObject);
AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
const char* cs_source = R"glsl(
#version 450
#extension GL_EXT_shader_64bit_indexing : enable
layout(set = 0, binding = 0) readonly buffer B { float x[]; } b;
void main(){ b.x.length64(); }
)glsl";
const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_source);
OneOffDescriptorSet descriptor_set(m_device,
{
{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
});
VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT, 1, &descriptor_set.layout_.handle());
m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpArrayLength-11807");
const vkt::Shader shader(*m_device, create_info);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeShader64BitIndexing, UntypedPointerLength64) {
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredExtensions(VK_KHR_SHADER_UNTYPED_POINTERS_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::shader64BitIndexing);
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredFeature(vkt::Feature::shaderUntypedPointers);
RETURN_IF_SKIP(Init());
const char* cs_source = R"(
OpCapability Shader
OpCapability UntypedPointersKHR
OpCapability Int64
OpExtension "SPV_KHR_untyped_pointers"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main" %b
OpExecutionMode %main LocalSize 1 1 1
OpDecorate %_runtimearr_float ArrayStride 4
OpDecorate %B Block
OpMemberDecorate %B 0 NonWritable
OpMemberDecorate %B 0 Offset 0
OpDecorate %b NonWritable
OpDecorate %b Binding 0
OpDecorate %b DescriptorSet 0
%void = OpTypeVoid
%4 = OpTypeFunction %void
%float = OpTypeFloat 32
%_runtimearr_float = OpTypeRuntimeArray %float
%B = OpTypeStruct %_runtimearr_float
%ptr = OpTypeUntypedPointerKHR StorageBuffer
%b = OpUntypedVariableKHR %ptr StorageBuffer %B
%ulong = OpTypeInt 64 0
%long = OpTypeInt 64 1
%main = OpFunction %void None %4
%6 = OpLabel
%13 = OpUntypedArrayLengthKHR %ulong %B %b 0
%15 = OpBitcast %long %13
OpReturn
OpFunctionEnd
)";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3, SPV_SOURCE_ASM);
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};
m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpArrayLength-11807");
pipe.CreateComputePipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeShader64BitIndexing, CoopVecMul) {
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredFeature(vkt::Feature::shader64BitIndexing);
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredFeature(vkt::Feature::shaderFloat16);
AddRequiredFeature(vkt::Feature::vulkanMemoryModel);
AddRequiredFeature(vkt::Feature::cooperativeVector);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
AddRequiredExtensions(VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
const char* cs_source = R"glsl(
#version 450
#extension GL_NV_cooperative_vector : enable
#extension GL_EXT_shader_explicit_arithmetic_types : enable
#extension GL_EXT_shader_64bit_indexing : enable
layout(set = 0, binding = 0) readonly buffer B { float x[]; } b;
void main() {
coopvecNV<float16_t, 16> A;
coopvecNV<float16_t, 16> R;
uint64_t offset = 0;
coopVecMatMulNV(R, A, gl_ComponentTypeFloat16NV, b.x, offset, gl_ComponentTypeFloat16NV, 16, 16, gl_CooperativeVectorMatrixLayoutInferencingOptimalNV, false, 0);
}
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3);
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};
m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpCooperativeVectorMatrixMulAddNV-11808");
pipe.CreateComputePipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeShader64BitIndexing, CoopVecLoad) {
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredFeature(vkt::Feature::shader64BitIndexing);
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredFeature(vkt::Feature::shaderFloat16);
AddRequiredFeature(vkt::Feature::vulkanMemoryModel);
AddRequiredFeature(vkt::Feature::cooperativeVector);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
AddRequiredExtensions(VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
const char* cs_source = R"glsl(
#version 450
#extension GL_NV_cooperative_vector : enable
#extension GL_EXT_shader_explicit_arithmetic_types : enable
#extension GL_EXT_shader_64bit_indexing : enable
layout(set = 0, binding = 0) readonly buffer B { float x[]; } b;
void main() {
coopvecNV<float16_t, 16> A;
uint64_t offset = 0;
coopVecLoadNV(A, b.x, offset);
}
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3);
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};
m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpCooperativeVectorLoadNV-11809");
pipe.CreateComputePipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeShader64BitIndexing, PipelineMissingEnable) {
SetTargetApiVersion(VK_API_VERSION_1_3);
// don't enable shader64BitIndexing
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
const char* cs_source = R"glsl(
#version 450
#extension GL_EXT_shader_64bit_indexing : enable
layout(set = 0, binding = 0) readonly buffer B { float x[]; } b;
void main(){ b.x.length64(); }
)glsl";
VkPipelineCreateFlags2CreateInfo pipe_flags2 = vku::InitStructHelper();
pipe_flags2.flags = VK_PIPELINE_CREATE_2_64_BIT_INDEXING_BIT_EXT;
CreateComputePipelineHelper pipe(*this, &pipe_flags2);
pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};
m_errorMonitor->SetDesiredError("VUID-VkComputePipelineCreateInfo-flags-11798");
pipe.CreateComputePipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeShader64BitIndexing, ShaderMissingEnable) {
SetTargetApiVersion(VK_API_VERSION_1_3);
// don't enable shader64BitIndexing
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredFeature(vkt::Feature::dynamicRendering);
AddRequiredFeature(vkt::Feature::shaderObject);
AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
const char* cs_source = R"glsl(
#version 450
#extension GL_EXT_shader_64bit_indexing : enable
layout(set = 0, binding = 0) readonly buffer B { float x[]; } b;
void main(){ b.x.length64(); }
)glsl";
const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_source);
OneOffDescriptorSet descriptor_set(m_device,
{
{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
});
VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT, 1, &descriptor_set.layout_.handle());
create_info.flags = VK_SHADER_CREATE_64_BIT_INDEXING_BIT_EXT;
m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-11758");
const vkt::Shader shader(*m_device, create_info);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeShader64BitIndexing, ConstantSizeOfLength64) {
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredExtensions(VK_KHR_SHADER_UNTYPED_POINTERS_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_SHADER_64BIT_INDEXING_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::descriptorHeap);
AddRequiredFeature(vkt::Feature::shader64BitIndexing);
AddRequiredFeature(vkt::Feature::shaderInt64);
AddRequiredFeature(vkt::Feature::shaderUntypedPointers);
RETURN_IF_SKIP(Init());
const char* cs_source = R"(
OpCapability Shader
OpCapability UntypedPointersKHR
OpCapability DescriptorHeapEXT
OpCapability Int64
OpExtension "SPV_EXT_descriptor_heap"
OpExtension "SPV_KHR_untyped_pointers"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint64 = OpTypeInt 64 0
%15 = OpTypeBufferEXT StorageBuffer
%16 = OpConstantSizeOfEXT %uint64 %15
%main = OpFunction %void None %3
%5 = OpLabel
OpReturn
OpFunctionEnd
)";
VkShaderObj cs_module = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_2, SPV_SOURCE_ASM);
VkPipelineCreateFlags2CreateInfoKHR pipe_flags2 = vku::InitStructHelper();
pipe_flags2.flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT;
CreateComputePipelineHelper pipe(*this, &pipe_flags2);
pipe.cp_ci_.stage = cs_module.GetStageCreateInfo();
pipe.cp_ci_.layout = VK_NULL_HANDLE;
m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpConstantSizeOfEXT-11475");
pipe.CreateComputePipeline(false);
m_errorMonitor->VerifyFound();
}