Skip to content
Open
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
106 changes: 106 additions & 0 deletions test_conformance/extensions/cl_khr_external_memory_ahb/test_ahb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.
//

#include "harness/deviceInfo.h"
#include "harness/compat.h"
#include "harness/kernelHelpers.h"
#include "harness/imageHelpers.h"
Expand Down Expand Up @@ -2336,3 +2337,108 @@ REGISTER_TEST(sub_buffer)
}
return TEST_PASS;
}

/* Testing clEnqueueMapBuffer & clEnqueueUnmapMemObject
* Create AHB
* Create CL buffer from AHB
* Write to AHB by locking it
* Verify write using clEnqueueMapBuffer clEnqueueUnmapMemObject
*/
REGISTER_TEST(enqueue_map_buffer)
{
cl_int err;
RandomSeed seed(gRandomSeed);

REQUIRE_EXTENSION("cl_khr_external_memory");
REQUIRE_EXTENSION("cl_khr_external_memory_android_hardware_buffer");

const ahb_format_table test_format = { AHARDWAREBUFFER_FORMAT_BLOB };

AHardwareBuffer_Desc aHardwareBufferDesc = { 0 };
aHardwareBufferDesc.format = test_format.aHardwareBufferFormat;
for (auto usage : test_buffer_usages)
{
aHardwareBufferDesc.usage = usage.usageFlags;
for (uint32_t buffer_size : test_buffer_sizes)
{
if (buffer_size > get_device_info_max_mem_alloc_size(device))
{
continue;
}

aHardwareBufferDesc.width = buffer_size;
aHardwareBufferDesc.height = 1;
aHardwareBufferDesc.layers = 1;

CHECK_AHARDWARE_BUFFER_SUPPORT(aHardwareBufferDesc, test_format);

AHardwareBufferWrapper aHardwareBuffer(&aHardwareBufferDesc);
log_info("Testing usage: %s, buffer size: %u\n",
ahardwareBufferDecodeUsageFlagsToString(usage.usageFlags)
.c_str(),
buffer_size);

cl_mem_properties props[] = {
CL_EXTERNAL_MEMORY_HANDLE_ANDROID_HARDWARE_BUFFER_KHR,
aHardwareBuffer.get_props(), 0
};

clMemWrapper buffer = clCreateBufferWithProperties(
context, props, CL_MEM_READ_WRITE, 0, nullptr, &err);
test_error(err, "Failed to create CL buffer from AHardwareBuffer");


void *hardware_buffer_data = nullptr;
int ahb_result = AHardwareBuffer_lock(
aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1,
nullptr, &hardware_buffer_data);
if (ahb_result != 0)
{
log_error("AHardwareBuffer_lock failed with code %d\n",
ahb_result);
return TEST_FAIL;
}

std::vector<uint8_t> host_buffer(buffer_size);

generate_random_data(ExplicitType::kUnsignedChar, buffer_size, seed,
host_buffer.data());

memcpy(hardware_buffer_data, host_buffer.data(), buffer_size);

ahb_result = AHardwareBuffer_unlock(aHardwareBuffer, nullptr);
if (ahb_result != 0)
{
log_error("AHardwareBuffer_unlock failed with code %d\n",
ahb_result);
return TEST_FAIL;
}

void *mapped_ptr =
clEnqueueMapBuffer(queue, buffer, CL_BLOCKING, CL_MAP_READ, 0,
buffer_size, 0, nullptr, nullptr, &err);
test_error(err, "clEnqueueMapBuffer failed");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that clEnqueueAcquireExternalMemObjectsKHR and clEnqueueReleaseExternalMemObjectsKHR are missing in this test and in lifetime_buffer, lifetime_image and sub_buffer.
They need to be called to comply with the spec:

Applications must acquire the memory objects that are created using external handles before they can be used by any OpenCL commands queued to a command-queue


uint8_t *mapped_data = static_cast<uint8_t *>(mapped_ptr);

for (size_t i = 0; i < buffer_size; ++i)
{
if (host_buffer[i] != mapped_data[i])
{
log_error(
"At position i=%zu expected value %u but got %u\n", i,
host_buffer[i], mapped_data[i]);
return TEST_FAIL;
}
}

err = clEnqueueUnmapMemObject(queue, buffer, mapped_ptr, 0, nullptr,
nullptr);
test_error(err, "clEnqueueUnmapMemObject failed");

err = clFinish(queue);
test_error(err, "clFinish failed");
}
}
return TEST_PASS;
}