Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to AHB VUs and Tests #2014

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 30 additions & 31 deletions layers/core_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3699,41 +3699,36 @@ bool CoreChecks::ValidateBindBufferMemory(VkBuffer buffer, VkDeviceMemory mem, V

const auto mem_info = GetDevMemState(mem);

// All validation using the buffer_state->requirements for external AHB is check in android only section
if (buffer_state->external_ahb == false) {
// Validate memory requirements alignment
if (SafeModulo(memoryOffset, buffer_state->requirements.alignment) != 0) {
const char *vuid = bind_buffer_mem_2 ? "VUID-VkBindBufferMemoryInfo-memoryOffset-01600"
: "VUID-vkBindBufferMemory-memoryOffset-01036";
skip |= LogError(buffer, vuid,
"%s: memoryOffset is 0x%" PRIxLEAST64
" but must be an integer multiple of the VkMemoryRequirements::alignment value 0x%" PRIxLEAST64
", returned from a call to vkGetBufferMemoryRequirements with buffer.",
api_name, memoryOffset, buffer_state->requirements.alignment);
}
// Validate memory requirements alignment
if (SafeModulo(memoryOffset, buffer_state->requirements.alignment) != 0) {
const char *vuid =
bind_buffer_mem_2 ? "VUID-VkBindBufferMemoryInfo-memoryOffset-01600" : "VUID-vkBindBufferMemory-memoryOffset-01036";
skip |= LogError(buffer, vuid,
"%s: memoryOffset is 0x%" PRIxLEAST64
" but must be an integer multiple of the VkMemoryRequirements::alignment value 0x%" PRIxLEAST64
", returned from a call to vkGetBufferMemoryRequirements with buffer.",
api_name, memoryOffset, buffer_state->requirements.alignment);
}

if (mem_info) {
// Validate bound memory range information
skip |= ValidateInsertBufferMemoryRange(buffer, mem_info, memoryOffset, api_name);
if (mem_info) {
// Validate bound memory range information
skip |= ValidateInsertBufferMemoryRange(buffer, mem_info, memoryOffset, api_name);

const char *mem_type_vuid =
bind_buffer_mem_2 ? "VUID-VkBindBufferMemoryInfo-memory-01599" : "VUID-vkBindBufferMemory-memory-01035";
skip |= ValidateMemoryTypes(mem_info, buffer_state->requirements.memoryTypeBits, api_name, mem_type_vuid);
const char *mem_type_vuid =
bind_buffer_mem_2 ? "VUID-VkBindBufferMemoryInfo-memory-01599" : "VUID-vkBindBufferMemory-memory-01035";
skip |= ValidateMemoryTypes(mem_info, buffer_state->requirements.memoryTypeBits, api_name, mem_type_vuid);

// Validate memory requirements size
if (buffer_state->requirements.size > (mem_info->alloc_info.allocationSize - memoryOffset)) {
const char *vuid =
bind_buffer_mem_2 ? "VUID-VkBindBufferMemoryInfo-size-01601" : "VUID-vkBindBufferMemory-size-01037";
skip |= LogError(buffer, vuid,
"%s: memory size minus memoryOffset is 0x%" PRIxLEAST64
" but must be at least as large as VkMemoryRequirements::size value 0x%" PRIxLEAST64
", returned from a call to vkGetBufferMemoryRequirements with buffer.",
api_name, mem_info->alloc_info.allocationSize - memoryOffset, buffer_state->requirements.size);
}
// Validate memory requirements size
if (buffer_state->requirements.size > (mem_info->alloc_info.allocationSize - memoryOffset)) {
const char *vuid =
bind_buffer_mem_2 ? "VUID-VkBindBufferMemoryInfo-size-01601" : "VUID-vkBindBufferMemory-size-01037";
skip |= LogError(buffer, vuid,
"%s: memory size minus memoryOffset is 0x%" PRIxLEAST64
" but must be at least as large as VkMemoryRequirements::size value 0x%" PRIxLEAST64
", returned from a call to vkGetBufferMemoryRequirements with buffer.",
api_name, mem_info->alloc_info.allocationSize - memoryOffset, buffer_state->requirements.size);
}
}

if (mem_info) {
// Validate dedicated allocation
if (mem_info->is_dedicated && ((mem_info->dedicated_buffer != buffer) || (memoryOffset != 0))) {
const char *vuid =
Expand Down Expand Up @@ -10413,7 +10408,11 @@ bool CoreChecks::ValidateBindImageMemory(uint32_t bindInfoCount, const VkBindIma

if (mem_info) {
// Validate bound memory range information
skip |= ValidateInsertImageMemoryRange(bindInfo.image, mem_info, bindInfo.memoryOffset, error_prefix);
// if memory is exported to an AHB then the mem_info->allocationSize must be zero and this check is not needed
if ((mem_info->is_export == false) || ((mem_info->export_handle_type_flags &
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) == 0)) {
skip |= ValidateInsertImageMemoryRange(bindInfo.image, mem_info, bindInfo.memoryOffset, error_prefix);
}

// Validate dedicated allocation
if (mem_info->is_dedicated) {
Expand Down
5 changes: 1 addition & 4 deletions layers/state_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,10 +429,7 @@ void ValidationStateTracker::PostCallRecordCreateBuffer(VkDevice device, const V
RecordCreateBufferANDROID(pCreateInfo, buffer_state.get());
}
// Get a set of requirements in the case the app does not
// External AHB memory can't be queried until after memory is bound
if (buffer_state->external_ahb == false) {
DispatchGetBufferMemoryRequirements(device, *pBuffer, &buffer_state->requirements);
}
DispatchGetBufferMemoryRequirements(device, *pBuffer, &buffer_state->requirements);

buffer_state->unprotected = ((pCreateInfo->flags & VK_BUFFER_CREATE_PROTECTED_BIT) == 0);

Expand Down
103 changes: 103 additions & 0 deletions tests/vklayertests_others.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5230,6 +5230,11 @@ TEST_F(VkLayerTest, AndroidHardwareBufferCreateImageView) {
SetTargetApiVersion(VK_API_VERSION_1_1);
ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));

if (IsPlatform(kGalaxyS10)) {
printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
return;
}

if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
// Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
(DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
Expand Down Expand Up @@ -5622,6 +5627,104 @@ TEST_F(VkLayerTest, AndroidHardwareBufferExporttBuffer) {
vk::DestroyImage(dev, img, NULL);
}

TEST_F(VkLayerTest, AndroidHardwareBufferInvalidBindBufferMemory) {
TEST_DESCRIPTION("Validate binding AndroidHardwareBuffer VkBuffer act same as non-AHB buffers.");

SetTargetApiVersion(VK_API_VERSION_1_1);
ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));

if (IsPlatform(kGalaxyS10)) {
printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
return;
}

if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
// Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
(DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
} else {
printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
return;
}

ASSERT_NO_FATAL_FAILURE(InitState());

// Allocate an AHardwareBuffer
AHardwareBuffer *ahb;
AHardwareBuffer_Desc ahb_desc = {};
ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
ahb_desc.width = 64;
ahb_desc.height = 1;
ahb_desc.layers = 1;
ahb_desc.stride = 1;
AHardwareBuffer_allocate(&ahb_desc, &ahb);

VkExternalMemoryBufferCreateInfo ext_buf_info = {};
ext_buf_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR;
ext_buf_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;

VkBufferCreateInfo buffer_create_info = {};
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_create_info.pNext = &ext_buf_info;
buffer_create_info.size = 1 << 20; // 1 MB
buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

VkBuffer buffer = VK_NULL_HANDLE;
vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);

// Try to get memory requirements prior to binding memory
VkMemoryRequirements mem_reqs;
vk::GetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);

VkImportAndroidHardwareBufferInfoANDROID import_ahb_Info = {};
import_ahb_Info.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
import_ahb_Info.pNext = nullptr;
import_ahb_Info.buffer = ahb;

VkMemoryAllocateInfo memory_info = {};
memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memory_info.pNext = &import_ahb_Info;
memory_info.allocationSize = mem_reqs.size + mem_reqs.alignment; // save room for offset
bool has_memtype = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &memory_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (!has_memtype) {
printf("%s No invalid memory type index could be found; skipped.\n", kSkipPrefix);
AHardwareBuffer_release(ahb);
vk::DestroyBuffer(m_device->device(), buffer, nullptr);
return;
}

VkDeviceMemory memory = VK_NULL_HANDLE;
VkResult result = vk::AllocateMemory(m_device->device(), &memory_info, NULL, &memory);
if ((memory == VK_NULL_HANDLE) || (result != VK_SUCCESS)) {
printf("%s This test failed to allocate memory for importing\n", kSkipPrefix);
return;
}

if (mem_reqs.alignment > 1) {
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-memoryOffset-01036");
vk::BindBufferMemory(device(), buffer, memory, 1);
m_errorMonitor->VerifyFound();
}

VkDeviceSize buffer_offset = (mem_reqs.size - 1) & ~(mem_reqs.alignment - 1);
if (buffer_offset > 0) {
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-size-01037");
vk::BindBufferMemory(device(), buffer, memory, buffer_offset);
m_errorMonitor->VerifyFound();
}

vk::DestroyBuffer(m_device->device(), buffer, nullptr);
vk::FreeMemory(m_device->device(), memory, nullptr);
}

TEST_F(VkLayerTest, AndroidHardwareBufferImportBufferHandleType) {
TEST_DESCRIPTION("Don't use proper resource handleType for import buffer");

Expand Down
Loading