blob: 01ca72a94d65c43140914824a3de4a2e5998d501 [file]
/*
* Copyright (c) 2020-2026 The Khronos Group Inc.
* Copyright (c) 2020-2026 Valve Corporation
* Copyright (c) 2020-2026 LunarG, Inc.
* Copyright (c) 2020-2026 Google, Inc.
*
* 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 <vulkan/vulkan_core.h>
#include <cstdint>
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include "../framework/descriptor_helper.h"
#include "../framework/gpu_av_helper.h"
// Until we land the glsl/spirv tooling, these are based on
//
// layout (set = 0, binding = 0) buffer SSBO {
// uint data;
// } x;
//
// layout (set = 0, binding = 1) uniform UBO {
// uint data;
// } y;
//
// void main() {
// uint a = y.data;
// x.data = a;
// }
//
// void main() {
// DebugDescriptor(x);
// uint a = y.data;
// x.data = a;
// }
[[maybe_unused]] static const uint32_t spv_simple_size = 168;
[[maybe_unused]] static const uint32_t spv_simple_data[168] = {
0x07230203, 0x00010500, 0x00070000, 0x00000018, 0x00000000, 0x00020011, 0x00000001, 0x0008000a, 0x5f565053, 0x5f52484b,
0x5f6e6f6e, 0x616d6573, 0x6369746e, 0x666e695f, 0x0000006f, 0x0009000b, 0x00000001, 0x536e6f4e, 0x6e616d65, 0x2e636974,
0x75626544, 0x73654467, 0x70697263, 0x00726f74, 0x0003000e, 0x00000000, 0x00000001, 0x0007000f, 0x00000005, 0x00000002,
0x6e69616d, 0x00000000, 0x00000003, 0x00000004, 0x00060010, 0x00000002, 0x00000011, 0x00000001, 0x00000001, 0x00000001,
0x00030047, 0x00000005, 0x00000002, 0x00050048, 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000003,
0x00000021, 0x00000001, 0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00030047, 0x00000006, 0x00000002, 0x00050048,
0x00000006, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000004, 0x00000021, 0x00000000, 0x00040047, 0x00000004,
0x00000022, 0x00000000, 0x00020013, 0x00000007, 0x00030021, 0x00000008, 0x00000007, 0x00040015, 0x00000009, 0x00000020,
0x00000000, 0x00040020, 0x0000000a, 0x00000007, 0x00000009, 0x0003001e, 0x00000005, 0x00000009, 0x00040020, 0x0000000b,
0x00000002, 0x00000005, 0x0004003b, 0x0000000b, 0x00000003, 0x00000002, 0x00040015, 0x0000000c, 0x00000020, 0x00000001,
0x0004002b, 0x0000000c, 0x0000000d, 0x00000000, 0x00040020, 0x0000000e, 0x00000002, 0x00000009, 0x0003001e, 0x00000006,
0x00000009, 0x00040020, 0x0000000f, 0x0000000c, 0x00000006, 0x0004003b, 0x0000000f, 0x00000004, 0x0000000c, 0x00040020,
0x00000010, 0x0000000c, 0x00000009, 0x00050036, 0x00000007, 0x00000002, 0x00000000, 0x00000008, 0x000200f8, 0x00000011,
0x0004003b, 0x0000000a, 0x00000012, 0x00000007, 0x0008000c, 0x00000007, 0x00000013, 0x00000001, 0x00000001, 0x00000004,
0x0000000d, 0x0000000d, 0x00050041, 0x0000000e, 0x00000014, 0x00000003, 0x0000000d, 0x0004003d, 0x00000009, 0x00000015,
0x00000014, 0x0003003e, 0x00000012, 0x00000015, 0x0004003d, 0x00000009, 0x00000016, 0x00000012, 0x00050041, 0x00000010,
0x00000017, 0x00000004, 0x0000000d, 0x0003003e, 0x00000017, 0x00000016, 0x000100fd, 0x00010038};
// void main() {
// uint a = y.data;
// x.data = a;
// DebugDescriptorAll();
// }
[[maybe_unused]] static const uint32_t spv_simple_all_size = 166;
[[maybe_unused]] static const uint32_t spv_simple_all_data[166] = {
0x07230203, 0x00010500, 0x00070000, 0x00000018, 0x00000000, 0x00020011, 0x00000001, 0x0008000a, 0x5f565053, 0x5f52484b,
0x5f6e6f6e, 0x616d6573, 0x6369746e, 0x666e695f, 0x0000006f, 0x0009000b, 0x00000001, 0x536e6f4e, 0x6e616d65, 0x2e636974,
0x75626544, 0x73654467, 0x70697263, 0x00726f74, 0x0003000e, 0x00000000, 0x00000001, 0x0007000f, 0x00000005, 0x00000002,
0x6e69616d, 0x00000000, 0x00000003, 0x00000004, 0x00060010, 0x00000002, 0x00000011, 0x00000001, 0x00000001, 0x00000001,
0x00030047, 0x00000005, 0x00000002, 0x00050048, 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000003,
0x00000021, 0x00000001, 0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00030047, 0x00000006, 0x00000002, 0x00050048,
0x00000006, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000004, 0x00000021, 0x00000000, 0x00040047, 0x00000004,
0x00000022, 0x00000000, 0x00020013, 0x00000007, 0x00030021, 0x00000008, 0x00000007, 0x00040015, 0x00000009, 0x00000020,
0x00000000, 0x00040020, 0x0000000a, 0x00000007, 0x00000009, 0x0003001e, 0x00000005, 0x00000009, 0x00040020, 0x0000000b,
0x00000002, 0x00000005, 0x0004003b, 0x0000000b, 0x00000003, 0x00000002, 0x00040015, 0x0000000c, 0x00000020, 0x00000001,
0x0004002b, 0x0000000c, 0x0000000d, 0x00000000, 0x00040020, 0x0000000e, 0x00000002, 0x00000009, 0x0003001e, 0x00000006,
0x00000009, 0x00040020, 0x0000000f, 0x0000000c, 0x00000006, 0x0004003b, 0x0000000f, 0x00000004, 0x0000000c, 0x00040020,
0x00000010, 0x0000000c, 0x00000009, 0x00050036, 0x00000007, 0x00000002, 0x00000000, 0x00000008, 0x000200f8, 0x00000011,
0x0004003b, 0x0000000a, 0x00000012, 0x00000007, 0x00050041, 0x0000000e, 0x00000013, 0x00000003, 0x0000000d, 0x0004003d,
0x00000009, 0x00000014, 0x00000013, 0x0003003e, 0x00000012, 0x00000014, 0x0004003d, 0x00000009, 0x00000015, 0x00000012,
0x00050041, 0x00000010, 0x00000016, 0x00000004, 0x0000000d, 0x0003003e, 0x00000016, 0x00000015, 0x0006000c, 0x00000007,
0x00000017, 0x00000001, 0x00000002, 0x0000000d, 0x000100fd, 0x00010038};
// void main() {
// DebugDescriptor(x, gl_earlyReturn);
// uint a = y.data;
// x.data = a;
// }
[[maybe_unused]] static const uint32_t spv_return_early_size = 172;
[[maybe_unused]] static const uint32_t spv_return_early_data[172] = {
0x07230203, 0x00010500, 0x00070000, 0x00000019, 0x00000000, 0x00020011, 0x00000001, 0x0008000a, 0x5f565053, 0x5f52484b,
0x5f6e6f6e, 0x616d6573, 0x6369746e, 0x666e695f, 0x0000006f, 0x0009000b, 0x00000001, 0x536e6f4e, 0x6e616d65, 0x2e636974,
0x75626544, 0x73654467, 0x70697263, 0x00726f74, 0x0003000e, 0x00000000, 0x00000001, 0x0007000f, 0x00000005, 0x00000002,
0x6e69616d, 0x00000000, 0x00000003, 0x00000004, 0x00060010, 0x00000002, 0x00000011, 0x00000001, 0x00000001, 0x00000001,
0x00030047, 0x00000005, 0x00000002, 0x00050048, 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000003,
0x00000021, 0x00000001, 0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00030047, 0x00000006, 0x00000002, 0x00050048,
0x00000006, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000004, 0x00000021, 0x00000000, 0x00040047, 0x00000004,
0x00000022, 0x00000000, 0x00020013, 0x00000007, 0x00030021, 0x00000008, 0x00000007, 0x00040015, 0x00000009, 0x00000020,
0x00000000, 0x00040020, 0x0000000a, 0x00000007, 0x00000009, 0x0003001e, 0x00000005, 0x00000009, 0x00040020, 0x0000000b,
0x00000002, 0x00000005, 0x0004003b, 0x0000000b, 0x00000003, 0x00000002, 0x00040015, 0x0000000c, 0x00000020, 0x00000001,
0x0004002b, 0x0000000c, 0x0000000d, 0x00000000, 0x0004002b, 0x0000000c, 0x0000000e, 0x00000001, 0x00040020, 0x0000000f,
0x00000002, 0x00000009, 0x0003001e, 0x00000006, 0x00000009, 0x00040020, 0x00000010, 0x0000000c, 0x00000006, 0x0004003b,
0x00000010, 0x00000004, 0x0000000c, 0x00040020, 0x00000011, 0x0000000c, 0x00000009, 0x00050036, 0x00000007, 0x00000002,
0x00000000, 0x00000008, 0x000200f8, 0x00000012, 0x0004003b, 0x0000000a, 0x00000013, 0x00000007, 0x0008000c, 0x00000007,
0x00000014, 0x00000001, 0x00000001, 0x00000004, 0x0000000d, 0x0000000e, 0x00050041, 0x0000000f, 0x00000015, 0x00000003,
0x0000000d, 0x0004003d, 0x00000009, 0x00000016, 0x00000015, 0x0003003e, 0x00000013, 0x00000016, 0x0004003d, 0x00000009,
0x00000017, 0x00000013, 0x00050041, 0x00000011, 0x00000018, 0x00000004, 0x0000000d, 0x0003003e, 0x00000018, 0x00000017,
0x000100fd, 0x00010038};
// void main() {
// DebugDescriptorAll(gl_earlyReturn);
// uint a = y.data;
// x.data = a;
// }
[[maybe_unused]] static const uint32_t spv_return_early_all_size = 170;
[[maybe_unused]] static const uint32_t spv_return_early_all_data[170] = {
0x07230203, 0x00010500, 0x00070000, 0x00000019, 0x00000000, 0x00020011, 0x00000001, 0x0008000a, 0x5f565053, 0x5f52484b,
0x5f6e6f6e, 0x616d6573, 0x6369746e, 0x666e695f, 0x0000006f, 0x0009000b, 0x00000001, 0x536e6f4e, 0x6e616d65, 0x2e636974,
0x75626544, 0x73654467, 0x70697263, 0x00726f74, 0x0003000e, 0x00000000, 0x00000001, 0x0007000f, 0x00000005, 0x00000002,
0x6e69616d, 0x00000000, 0x00000003, 0x00000004, 0x00060010, 0x00000002, 0x00000011, 0x00000001, 0x00000001, 0x00000001,
0x00030047, 0x00000005, 0x00000002, 0x00050048, 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000003,
0x00000021, 0x00000001, 0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00030047, 0x00000006, 0x00000002, 0x00050048,
0x00000006, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000004, 0x00000021, 0x00000000, 0x00040047, 0x00000004,
0x00000022, 0x00000000, 0x00020013, 0x00000007, 0x00030021, 0x00000008, 0x00000007, 0x00040015, 0x00000009, 0x00000020,
0x00000000, 0x00040020, 0x0000000a, 0x00000007, 0x00000009, 0x0003001e, 0x00000005, 0x00000009, 0x00040020, 0x0000000b,
0x00000002, 0x00000005, 0x0004003b, 0x0000000b, 0x00000003, 0x00000002, 0x00040015, 0x0000000c, 0x00000020, 0x00000001,
0x0004002b, 0x0000000c, 0x0000000d, 0x00000000, 0x0004002b, 0x0000000c, 0x0000000e, 0x00000001, 0x00040020, 0x0000000f,
0x00000002, 0x00000009, 0x0003001e, 0x00000006, 0x00000009, 0x00040020, 0x00000010, 0x0000000c, 0x00000006, 0x0004003b,
0x00000010, 0x00000004, 0x0000000c, 0x00040020, 0x00000011, 0x0000000c, 0x00000009, 0x00050036, 0x00000007, 0x00000002,
0x00000000, 0x00000008, 0x000200f8, 0x00000012, 0x0004003b, 0x0000000a, 0x00000013, 0x00000007, 0x0006000c, 0x00000007,
0x00000014, 0x00000001, 0x00000002, 0x0000000e, 0x00050041, 0x0000000f, 0x00000015, 0x00000003, 0x0000000d, 0x0004003d,
0x00000009, 0x00000016, 0x00000015, 0x0003003e, 0x00000013, 0x00000016, 0x0004003d, 0x00000009, 0x00000017, 0x00000013,
0x00050041, 0x00000011, 0x00000018, 0x00000004, 0x0000000d, 0x0003003e, 0x00000018, 0x00000017, 0x000100fd, 0x00010038};
static const VkLayerSettingEXT kDescriptorSetting = {OBJECT_LAYER_NAME, "debug_descriptor", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1,
&kVkTrue};
static VkLayerSettingsCreateInfoEXT kDescriptorSettingCreateInfo = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1,
&kDescriptorSetting};
class NegativeDebugDescriptor : public VkLayerTest {
public:
void InitDebugDescriptor();
};
void NegativeDebugDescriptor::InitDebugDescriptor() {
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework(&kDescriptorSettingCreateInfo));
RETURN_IF_SKIP(InitState());
if (!CanEnableGpuAV(*this)) {
GTEST_SKIP() << "Requirements for GPU-AV are not met";
}
}
TEST_F(NegativeDebugDescriptor, BufferBasic) {
SetTargetApiVersion(VK_API_VERSION_1_2);
AddRequiredExtensions(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::descriptorBuffer);
AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
RETURN_IF_SKIP(InitDebugDescriptor());
VkPhysicalDeviceDescriptorBufferPropertiesEXT descriptor_buffer_properties = vku::InitStructHelper();
GetPhysicalDeviceProperties2(descriptor_buffer_properties);
vkt::Buffer ssbo_buffer(*m_device, 64, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, vkt::device_address);
vkt::Buffer ubo_buffer(*m_device, 64, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, vkt::device_address);
std::vector<VkDescriptorSetLayoutBinding> bindings = {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
{1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}};
vkt::DescriptorSetLayout ds_layout(*m_device, bindings, VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT);
vkt::PipelineLayout pipeline_layout(*m_device, {&ds_layout});
VkDeviceSize ds_layout_size = ds_layout.GetDescriptorBufferSize();
vkt::Buffer descriptor_buffer(*m_device, ds_layout_size * 4, VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT,
vkt::device_address);
vkt::DescriptorGetInfo get_info_ssbo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ssbo_buffer, 32);
uint8_t* mapped_descriptor_data = (uint8_t*)descriptor_buffer.Memory().Map();
vk::GetDescriptorEXT(device(), get_info_ssbo, descriptor_buffer_properties.storageBufferDescriptorSize,
mapped_descriptor_data + ds_layout.GetDescriptorBufferBindingOffset(0));
vkt::DescriptorGetInfo get_info_ubo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ubo_buffer, 16);
vk::GetDescriptorEXT(device(), get_info_ubo, descriptor_buffer_properties.uniformBufferDescriptorSize,
mapped_descriptor_data + ds_layout.GetDescriptorBufferBindingOffset(1));
VkShaderModuleCreateInfo module_ci = vku::InitStructHelper();
module_ci.codeSize = spv_simple_size * sizeof(uint32_t);
module_ci.pCode = spv_simple_data;
// spirv-val will not be happy without our spirv headers added
m_errorMonitor->SetAllowedFailureMsg("VUID-VkShaderModuleCreateInfo-pCode-08737");
vkt::ShaderModule module(*m_device, module_ci);
VkPipelineShaderStageCreateInfo stage_info = vku::InitStructHelper();
stage_info.flags = 0;
stage_info.stage = VK_SHADER_STAGE_COMPUTE_BIT;
stage_info.module = module;
stage_info.pName = "main";
CreateComputePipelineHelper pipe(*this);
pipe.cp_ci_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
pipe.cp_ci_.layout = pipeline_layout;
pipe.cp_ci_.stage = stage_info;
pipe.CreateComputePipeline(false);
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipe);
VkDescriptorBufferBindingInfoEXT descriptor_buffer_binding_info = vku::InitStructHelper();
descriptor_buffer_binding_info.address = descriptor_buffer.Address();
descriptor_buffer_binding_info.usage = VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT;
vk::CmdBindDescriptorBuffersEXT(m_command_buffer, 1, &descriptor_buffer_binding_info);
uint32_t buffer_index = 0;
VkDeviceSize buffer_offset = 0;
vk::CmdSetDescriptorBufferOffsetsEXT(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, 0, 1, &buffer_index,
&buffer_offset);
vk::CmdDispatch(m_command_buffer, 1, 1, 1);
m_command_buffer.End();
m_default_queue->SubmitAndWait(m_command_buffer);
}