@@ -924,4 +924,126 @@ TEST_F(NegativeGpuAVDescriptorHeap, ShaderObjects) {
924924
925925 m_default_queue->SubmitAndWait (m_command_buffer);
926926 m_errorMonitor->VerifyFound ();
927- }
927+ }
928+
929+ TEST_F (NegativeGpuAVDescriptorHeap, PushAddressUniformBufferUsage) {
930+ AddRequiredFeature (vkt::Feature::bufferDeviceAddress);
931+ AddRequiredFeature (vkt::Feature::vertexPipelineStoresAndAtomics);
932+ RETURN_IF_SKIP (InitGpuAVDescriptorHeap ());
933+ InitRenderTarget ();
934+
935+ vkt::Buffer read_buffer (*m_device, sizeof (uint32_t ) * 4 , VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT_KHR, vkt::device_address);
936+ uint32_t * read_data = static_cast <uint32_t *>(read_buffer.Memory ().Map ());
937+ for (uint32_t i = 0 ; i < 4 ; ++i) {
938+ read_data[i] = i + 1 ;
939+ }
940+ vkt::Buffer write_buffer (*m_device, sizeof (uint32_t ) * 4 , VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT_KHR, vkt::device_address);
941+
942+ const uint32_t read_offset = 48u ;
943+ const VkDeviceSize write_offset =
944+ Align (read_offset + heap_props.bufferDescriptorAlignment * 7u , heap_props.bufferDescriptorAlignment );
945+ const VkDeviceSize resource_stride = heap_props.bufferDescriptorSize ;
946+ const VkDeviceSize descriptor_size = AlignResource (write_offset + resource_stride);
947+ const VkDeviceSize heap_size = descriptor_size + heap_props.minResourceHeapReservedRange ;
948+
949+ vkt::Buffer heap (*m_device, heap_size, VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT, vkt::device_address);
950+ uint8_t * heap_data = static_cast <uint8_t *>(heap.Memory ().Map ());
951+
952+ VkHostAddressRangeEXT descriptor_host;
953+ descriptor_host.address = heap_data + write_offset;
954+ descriptor_host.size = resource_stride;
955+
956+ VkDeviceAddressRangeEXT device_range;
957+ device_range.address = write_buffer.Address ();
958+ device_range.size = write_buffer.CreateInfo ().size ;
959+
960+ VkResourceDescriptorInfoEXT descriptor_info;
961+ descriptor_info = vku::InitStructHelper ();
962+ descriptor_info.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
963+ descriptor_info.data .pAddressRange = &device_range;
964+
965+ vk::WriteResourceDescriptorsEXT (*m_device, 1u , &descriptor_info, &descriptor_host);
966+
967+ VkDescriptorSetAndBindingMappingEXT mappings[2 ];
968+ mappings[0 ] = vku::InitStructHelper ();
969+ mappings[0 ].descriptorSet = 2u ;
970+ mappings[0 ].firstBinding = 3u ;
971+ mappings[0 ].bindingCount = 1u ;
972+ mappings[0 ].resourceMask = VK_SPIRV_RESOURCE_TYPE_UNIFORM_BUFFER_BIT_EXT;
973+ mappings[0 ].source = VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_ADDRESS_EXT;
974+ mappings[0 ].sourceData .pushAddressOffset = static_cast <uint32_t >(read_offset);
975+ mappings[1 ] = vku::InitStructHelper ();
976+ mappings[1 ].descriptorSet = 1u ;
977+ mappings[1 ].firstBinding = 0u ;
978+ mappings[1 ].bindingCount = 1u ;
979+ mappings[1 ].resourceMask = VK_SPIRV_RESOURCE_TYPE_READ_WRITE_STORAGE_BUFFER_BIT_EXT;
980+ mappings[1 ].source = VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_CONSTANT_OFFSET_EXT;
981+ mappings[1 ].sourceData .constantOffset .heapOffset = static_cast <uint32_t >(write_offset);
982+ mappings[1 ].sourceData .constantOffset .heapArrayStride = 0u ;
983+
984+ VkShaderDescriptorSetAndBindingMappingInfoEXT mapping_info = vku::InitStructHelper ();
985+ mapping_info.mappingCount = 2u ;
986+ mapping_info.pMappings = mappings;
987+
988+ char const * vert_source = R"glsl(
989+ #version 450
990+ layout(set = 2, binding = 3) uniform ReadData {
991+ uvec4 read_data;
992+ };
993+ layout(set = 1, binding = 0) buffer WriteData {
994+ uvec4 write_data;
995+ };
996+ void main() {
997+ if (gl_VertexIndex == 0) {
998+ write_data[0] = read_data[3];
999+ }
1000+ gl_Position = vec4(1.0f);
1001+ gl_PointSize = 1.0f;
1002+ }
1003+ )glsl" ;
1004+
1005+ VkShaderObj vert_module = VkShaderObj (*m_device, vert_source, VK_SHADER_STAGE_VERTEX_BIT);
1006+ VkShaderObj frag_module = VkShaderObj (*m_device, kFragmentMinimalGlsl , VK_SHADER_STAGE_FRAGMENT_BIT);
1007+
1008+ VkPipelineCreateFlags2CreateInfoKHR pipeline_create_flags_2_create_info = vku::InitStructHelper ();
1009+ pipeline_create_flags_2_create_info.flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT;
1010+
1011+ VkPipelineShaderStageCreateInfo stages[2 ];
1012+ stages[0 ] = vert_module.GetStageCreateInfo ();
1013+ stages[0 ].pNext = &mapping_info;
1014+ stages[1 ] = frag_module.GetStageCreateInfo ();
1015+
1016+ CreatePipelineHelper descriptor_heap_pipe (*this , &pipeline_create_flags_2_create_info);
1017+ descriptor_heap_pipe.gp_ci_ .layout = VK_NULL_HANDLE;
1018+ descriptor_heap_pipe.gp_ci_ .stageCount = 2u ;
1019+ descriptor_heap_pipe.gp_ci_ .pStages = stages;
1020+ descriptor_heap_pipe.CreateGraphicsPipeline (false );
1021+
1022+ VkDeviceAddress read_address = read_buffer.Address ();
1023+
1024+ VkPushDataInfoEXT push_data = vku::InitStructHelper ();
1025+ push_data.offset = read_offset;
1026+ push_data.data .address = &read_address;
1027+ push_data.data .size = sizeof (read_address);
1028+
1029+ m_command_buffer.Begin ();
1030+ m_command_buffer.BeginRenderPass (m_renderPassBeginInfo);
1031+
1032+ vk::CmdBindPipeline (m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, descriptor_heap_pipe);
1033+
1034+ VkBindHeapInfoEXT bind_resource_info = vku::InitStructHelper ();
1035+ bind_resource_info.heapRange .address = heap.Address ();
1036+ bind_resource_info.heapRange .size = heap_size;
1037+ bind_resource_info.reservedRangeOffset = descriptor_size;
1038+ bind_resource_info.reservedRangeSize = heap_props.minResourceHeapReservedRange ;
1039+ vk::CmdBindResourceHeapEXT (m_command_buffer, &bind_resource_info);
1040+
1041+ vk::CmdPushDataEXT (m_command_buffer, &push_data);
1042+ vk::CmdDraw (m_command_buffer, 3u , 1u , 0u , 0u );
1043+
1044+ m_command_buffer.EndRenderPass ();
1045+ m_command_buffer.End ();
1046+ m_errorMonitor->SetDesiredError (" VUID-vkCmdDraw-None-11438" );
1047+ m_default_queue->SubmitAndWait (m_command_buffer);
1048+ m_errorMonitor->VerifyFound ();
1049+ }
0 commit comments