blob: 84dcf14a3e748148b4faedea514d503747f76869 [file]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/magma/magma.h>
#include <lib/magma/util/utils.h>
#include <lib/magma_client/test_util/inflight_list.h>
#include <lib/magma_client/test_util/magma_map_cpu.h>
#include <lib/magma_client/test_util/test_device_helper.h>
#include <magma_intel_gen_defs.h>
#include <vector>
#include <gtest/gtest.h>
namespace {
const uint32_t kPageSize = zx_system_get_page_size();
// Executes multiple simple command buffers over a context/connection.
class TestExecuteWithCount : public testing::TestWithParam<uint32_t> {
public:
void SetUp() override {
base_.InitializeFromVendorId(MAGMA_VENDOR_ID_INTEL);
ASSERT_EQ(MAGMA_STATUS_OK, magma_device_create_connection(base_.device(), &connection_));
ASSERT_EQ(MAGMA_STATUS_OK, magma_device_query(base_.device(), kMagmaIntelGenQueryExtraPageCount,
nullptr, &extra_page_count_));
ASSERT_EQ(MAGMA_STATUS_OK, magma_connection_create_context(connection_, &context_ids_[0]));
ASSERT_EQ(MAGMA_STATUS_OK, magma_connection_create_context(connection_, &context_ids_[1]));
}
void TearDown() override {
if (context_ids_[0])
magma_connection_release_context(connection_, context_ids_[0]);
if (context_ids_[1])
magma_connection_release_context(connection_, context_ids_[1]);
if (connection_)
magma_connection_release(connection_);
}
// Validate one command streamer waits for a semaphore, another command streamer signals it.
void SemaphoreWaitAndSignal(uint32_t context_count) {
constexpr uint64_t kMapFlags =
MAGMA_MAP_FLAG_READ | MAGMA_MAP_FLAG_WRITE | MAGMA_MAP_FLAG_EXECUTE;
constexpr uint32_t kPattern = 0xabcd1234;
const uint32_t kSize = kPageSize;
ASSERT_TRUE(context_count == 1 || context_count == 2);
uint64_t size;
magma_buffer_t wait_batch_buffer;
magma_buffer_id_t wait_batch_buffer_id;
ASSERT_EQ(MAGMA_STATUS_OK,
magma_connection_create_buffer(connection_, kSize, &size, &wait_batch_buffer,
&wait_batch_buffer_id));
magma_buffer_t signal_batch_buffer;
magma_buffer_id_t signal_batch_buffer_id;
ASSERT_EQ(MAGMA_STATUS_OK,
magma_connection_create_buffer(connection_, kSize, &size, &signal_batch_buffer,
&signal_batch_buffer_id));
magma_buffer_t semaphore_buffer;
magma_buffer_id_t semaphore_buffer_id;
ASSERT_EQ(MAGMA_STATUS_OK,
magma_connection_create_buffer(connection_, kSize, &size, &semaphore_buffer,
&semaphore_buffer_id));
EXPECT_EQ(MAGMA_STATUS_OK, magma_connection_map_buffer(connection_, gpu_addr_,
wait_batch_buffer, 0, size, kMapFlags));
gpu_addr_ += size + extra_page_count_ * kPageSize;
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_map_buffer(connection_, gpu_addr_, signal_batch_buffer, 0, size,
kMapFlags));
gpu_addr_ += size + extra_page_count_ * kPageSize;
EXPECT_EQ(MAGMA_STATUS_OK, magma_connection_map_buffer(connection_, gpu_addr_, semaphore_buffer,
0, size, kMapFlags));
// wait for memory location to be > 0
InitBatchSemaphoreWait(wait_batch_buffer, size, 0, gpu_addr_);
// write the memory location
InitBatchMemoryWrite(signal_batch_buffer, size, kPattern, gpu_addr_);
gpu_addr_ += size + extra_page_count_ * kPageSize;
// initialize semaphore location to 0
ClearBuffer(semaphore_buffer, size, 0);
magma::InflightList list;
{
// Wait for semaphore on render command streamer
magma_command_descriptor descriptor;
magma_exec_command_buffer command_buffer;
std::vector<magma_exec_resource> exec_resources;
InitCommand(&descriptor, &command_buffer, &exec_resources, wait_batch_buffer_id, kSize,
semaphore_buffer_id, kSize);
descriptor.flags = kMagmaIntelGenCommandBufferForRender;
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_execute_command(connection_, context_ids_[0], &descriptor));
for (auto resource : exec_resources) {
list.add(resource.buffer_id);
}
}
{
// Signal semaphore on render command streamer - this command buffer will just be queued on
// the first context while render CS is blocked on the semaphore.
magma_command_descriptor descriptor;
magma_exec_command_buffer command_buffer;
std::vector<magma_exec_resource> exec_resources;
InitCommand(&descriptor, &command_buffer, &exec_resources, signal_batch_buffer_id, kSize,
semaphore_buffer_id, kSize);
descriptor.flags = kMagmaIntelGenCommandBufferForRender;
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_execute_command(connection_, context_ids_[0], &descriptor));
for (auto resource : exec_resources) {
list.add(resource.buffer_id);
}
}
{
// Signal semaphore on video command streamer - this command buffer executes and unblocks the
// semaphore.
magma_command_descriptor descriptor;
magma_exec_command_buffer command_buffer;
std::vector<magma_exec_resource> exec_resources;
InitCommand(&descriptor, &command_buffer, &exec_resources, signal_batch_buffer_id, kSize,
semaphore_buffer_id, kSize);
descriptor.flags = kMagmaIntelGenCommandBufferForVideo;
uint32_t context = context_count == 2 ? context_ids_[1] : context_ids_[0];
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_execute_command(connection_, context, &descriptor));
for (auto resource : exec_resources) {
list.add(resource.buffer_id);
}
}
while (list.size()) {
uint64_t start_size = list.size();
magma::Status status =
list.WaitForCompletion(connection_, std::numeric_limits<int64_t>::max());
ASSERT_EQ(MAGMA_STATUS_OK, status.get());
list.ServiceCompletions(connection_);
ASSERT_LT(list.size(), start_size);
}
magma_connection_release_buffer(connection_, wait_batch_buffer);
magma_connection_release_buffer(connection_, signal_batch_buffer);
magma_connection_release_buffer(connection_, semaphore_buffer);
}
enum Mode {
RENDER_ONLY,
VIDEO_ONLY,
RENDER_AND_VIDEO_INTERLEAVED,
};
void MemoryWriteAndReadback(Mode mode, uint32_t count, uint32_t context_count) {
constexpr uint64_t kMapFlags =
MAGMA_MAP_FLAG_READ | MAGMA_MAP_FLAG_WRITE | MAGMA_MAP_FLAG_EXECUTE;
constexpr uint32_t kPattern = 0xabcd1234;
const uint32_t kSize = kPageSize;
std::vector<magma_buffer_t> batch_buffers;
std::vector<magma_buffer_id_t> batch_buffer_ids;
std::vector<magma_buffer_t> result_buffers;
std::vector<magma_buffer_id_t> result_buffer_ids;
ASSERT_TRUE(context_count == 1 || context_count == 2);
for (uint32_t i = 0; i < count; i++) {
uint64_t size;
magma_buffer_t batch_buffer;
magma_buffer_id_t batch_buffer_id;
ASSERT_EQ(MAGMA_STATUS_OK, magma_connection_create_buffer(connection_, kSize, &size,
&batch_buffer, &batch_buffer_id));
batch_buffers.push_back(batch_buffer);
batch_buffer_ids.push_back(batch_buffer_id);
magma_buffer_t result_buffer;
magma_buffer_id_t result_buffer_id;
ASSERT_EQ(MAGMA_STATUS_OK, magma_connection_create_buffer(connection_, kSize, &size,
&result_buffer, &result_buffer_id));
result_buffers.push_back(result_buffer);
result_buffer_ids.push_back(result_buffer_id);
EXPECT_EQ(MAGMA_STATUS_OK, magma_connection_map_buffer(connection_, gpu_addr_, batch_buffer,
0, size, kMapFlags));
gpu_addr_ += size + extra_page_count_ * kPageSize;
EXPECT_EQ(MAGMA_STATUS_OK, magma_connection_map_buffer(connection_, gpu_addr_, result_buffer,
0, size, kMapFlags));
InitBatchMemoryWrite(batch_buffer, size, kPattern, gpu_addr_);
gpu_addr_ += size + extra_page_count_ * kPageSize;
ClearBuffer(result_buffer, size, 0xfefefefe);
}
magma::InflightList list;
// Submit everything close together.
for (uint32_t i = 0; i < count; i++) {
magma_command_descriptor descriptor;
magma_exec_command_buffer command_buffer;
std::vector<magma_exec_resource> exec_resources;
InitCommand(&descriptor, &command_buffer, &exec_resources, batch_buffer_ids[i], kSize,
result_buffer_ids[i], kSize);
switch (mode) {
case RENDER_ONLY:
descriptor.flags = kMagmaIntelGenCommandBufferForRender;
break;
case VIDEO_ONLY:
descriptor.flags = kMagmaIntelGenCommandBufferForVideo;
break;
case RENDER_AND_VIDEO_INTERLEAVED:
descriptor.flags = (i % 2 == 0) ? kMagmaIntelGenCommandBufferForRender
: kMagmaIntelGenCommandBufferForVideo;
break;
}
{
uint32_t context = context_ids_[0];
if (context_count == 2 && (i % 2)) {
context = context_ids_[1];
}
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_execute_command(connection_, context, &descriptor));
}
for (auto resource : exec_resources) {
list.add(resource.buffer_id);
}
}
while (list.size()) {
uint64_t start_size = list.size();
magma::Status status =
list.WaitForCompletion(connection_, std::numeric_limits<int64_t>::max());
ASSERT_EQ(MAGMA_STATUS_OK, status.get());
list.ServiceCompletions(connection_);
ASSERT_LT(list.size(), start_size);
}
for (uint32_t i = 0; i < count; i++) {
uint32_t result;
ReadBufferAt(result_buffers[i], kSize, 0, &result);
EXPECT_EQ(kPattern, result) << " expected: 0x" << std::hex << kPattern << " got: 0x"
<< result;
magma_connection_release_buffer(connection_, batch_buffers[i]);
magma_connection_release_buffer(connection_, result_buffers[i]);
}
}
// Verifies independent presubmit queueing (pending wait semaphores) for multi engines.
void MemoryWriteEngineInterleavedPresubmitQueueing(int submit_count, int semaphore_count,
bool use_counter_semaphore = false) {
ASSERT_EQ(submit_count % 2, 0);
constexpr uint64_t kMapFlags =
MAGMA_MAP_FLAG_READ | MAGMA_MAP_FLAG_WRITE | MAGMA_MAP_FLAG_EXECUTE;
constexpr uint32_t kPattern = 0xabcd1234;
const uint32_t kSize = kPageSize;
constexpr uint64_t kOneSecondInNs = 1000000000ull;
struct Submit {
magma_buffer_t batch_buffer;
magma_buffer_id_t batch_buffer_id;
magma_buffer_t result_buffer;
magma_buffer_id_t result_buffer_id;
std::vector<magma_semaphore_t> wait_semaphores;
std::vector<magma_semaphore_t> signal_semaphores;
std::vector<magma_semaphore_id_t> semaphore_ids;
uint64_t command_buffer_flags;
};
std::vector<Submit> submits;
for (int i = 0; i < submit_count; i++) {
Submit submit = {};
uint64_t size;
ASSERT_EQ(MAGMA_STATUS_OK,
magma_connection_create_buffer(connection_, kSize, &size, &submit.batch_buffer,
&submit.batch_buffer_id));
ASSERT_EQ(MAGMA_STATUS_OK,
magma_connection_create_buffer(connection_, kSize, &size, &submit.result_buffer,
&submit.result_buffer_id));
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_map_buffer(connection_, gpu_addr_, submit.batch_buffer, 0, size,
kMapFlags));
gpu_addr_ += size + extra_page_count_ * kPageSize;
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_map_buffer(connection_, gpu_addr_, submit.result_buffer, 0, size,
kMapFlags));
InitBatchMemoryWrite(submit.batch_buffer, size, kPattern, gpu_addr_);
gpu_addr_ += size + extra_page_count_ * kPageSize;
ClearBuffer(submit.result_buffer, size, 0xfefefefe);
for (int i = 0; i < semaphore_count; i++) {
magma_semaphore_t semaphore;
magma_semaphore_id_t id;
#if defined(__Fuchsia__)
if (use_counter_semaphore) {
zx::counter counter;
ASSERT_EQ(ZX_OK, zx::counter::create(/*options=*/0, &counter));
ASSERT_EQ(MAGMA_STATUS_OK, magma_connection_import_semaphore2(
connection_, counter.release(),
MAGMA_IMPORT_SEMAPHORE_ONE_SHOT, &semaphore, &id));
} else
#endif
{
ASSERT_EQ(MAGMA_STATUS_OK,
magma_connection_create_semaphore(connection_, &semaphore, &id));
}
submit.wait_semaphores.push_back(semaphore);
submit.semaphore_ids.push_back(id);
}
for (int i = 0; i < semaphore_count; i++) {
magma_semaphore_t semaphore;
magma_semaphore_id_t id;
#if defined(__Fuchsia__)
if (use_counter_semaphore) {
zx::counter counter;
ASSERT_EQ(ZX_OK, zx::counter::create(/*options=*/0, &counter));
ASSERT_EQ(MAGMA_STATUS_OK, magma_connection_import_semaphore2(
connection_, counter.release(),
MAGMA_IMPORT_SEMAPHORE_ONE_SHOT, &semaphore, &id));
} else
#endif
{
ASSERT_EQ(MAGMA_STATUS_OK,
magma_connection_create_semaphore(connection_, &semaphore, &id));
}
submit.signal_semaphores.push_back(semaphore);
submit.semaphore_ids.push_back(id);
}
// Alternate between engines
if (i % 2 == 0) {
submit.command_buffer_flags = kMagmaIntelGenCommandBufferForRender;
} else {
submit.command_buffer_flags = kMagmaIntelGenCommandBufferForVideo;
}
submits.push_back(std::move(submit));
}
magma::InflightList list;
for (size_t i = 0; i < submits.size(); i++) {
magma_command_descriptor descriptor;
magma_exec_command_buffer command_buffer;
std::vector<magma_exec_resource> exec_resources;
InitCommand(&descriptor, &command_buffer, &exec_resources, submits[i].batch_buffer_id, kSize,
submits[i].result_buffer_id, kSize);
descriptor.wait_semaphore_count = semaphore_count;
descriptor.signal_semaphore_count = semaphore_count;
descriptor.semaphore_ids = submits[i].semaphore_ids.data();
descriptor.flags = submits[i].command_buffer_flags;
{
uint32_t context = context_ids_[0];
EXPECT_EQ(MAGMA_STATUS_OK,
magma_connection_execute_command(connection_, context, &descriptor));
}
for (auto resource : exec_resources) {
list.add(resource.buffer_id);
}
}
// Ensure signal semaphores not signaled
for (auto& submit : submits) {
for (size_t i = 0; i < submit.signal_semaphores.size(); i++) {
magma_poll_item_t item = {
.semaphore = submit.signal_semaphores[i],
.type = MAGMA_POLL_TYPE_SEMAPHORE,
.condition = MAGMA_POLL_CONDITION_SIGNALED,
};
EXPECT_EQ(MAGMA_STATUS_TIMED_OUT, magma_poll(&item, 1, /* timeout_ns= */ 0))
<< "signal semaphore index " << i;
}
}
// Signal wait semaphores for RCS
for (auto& submit : submits) {
if (submit.command_buffer_flags == kMagmaIntelGenCommandBufferForRender) {
for (size_t i = 0; i < submit.wait_semaphores.size(); i++) {
magma_semaphore_signal(submit.wait_semaphores[i]);
}
}
}
// Check signal semaphores
for (auto& submit : submits) {
for (size_t i = 0; i < submit.signal_semaphores.size(); i++) {
magma_poll_item_t item = {
.semaphore = submit.signal_semaphores[i],
.type = MAGMA_POLL_TYPE_SEMAPHORE,
.condition = MAGMA_POLL_CONDITION_SIGNALED,
};
if (submit.command_buffer_flags == kMagmaIntelGenCommandBufferForRender) {
EXPECT_EQ(MAGMA_STATUS_OK, magma_poll(&item, 1, kOneSecondInNs))
<< "signal semaphore index " << i;
} else {
EXPECT_EQ(MAGMA_STATUS_TIMED_OUT, magma_poll(&item, 1, /* timeout_ns= */ 0))
<< "signal semaphore index " << i;
}
}
}
// Signal wait semaphores for second engine
for (auto& submit : submits) {
if (submit.command_buffer_flags == kMagmaIntelGenCommandBufferForVideo) {
for (size_t i = 0; i < submit.wait_semaphores.size(); i++) {
magma_semaphore_signal(submit.wait_semaphores[i]);
}
}
}
// Check signal semaphores
for (auto& submit : submits) {
for (size_t i = 0; i < submit.signal_semaphores.size(); i++) {
magma_poll_item_t item = {
.semaphore = submit.signal_semaphores[i],
.type = MAGMA_POLL_TYPE_SEMAPHORE,
.condition = MAGMA_POLL_CONDITION_SIGNALED,
};
EXPECT_EQ(MAGMA_STATUS_OK, magma_poll(&item, 1, kOneSecondInNs))
<< "signal semaphore index " << i;
}
}
// Check completion notifications
while (list.size()) {
uint64_t start_size = list.size();
magma::Status status =
list.WaitForCompletion(connection_, std::numeric_limits<int64_t>::max());
ASSERT_EQ(MAGMA_STATUS_OK, status.get());
list.ServiceCompletions(connection_);
ASSERT_LT(list.size(), start_size);
}
// Check results and cleanup
for (size_t i = 0; i < submits.size(); i++) {
uint32_t result;
ReadBufferAt(submits[i].result_buffer, kSize, 0, &result);
EXPECT_EQ(kPattern, result) << "submit " << i << " expected: 0x" << std::hex << kPattern
<< " got: 0x" << result;
magma_connection_release_buffer(connection_, submits[i].batch_buffer);
magma_connection_release_buffer(connection_, submits[i].result_buffer);
for (auto& semaphore : submits[i].wait_semaphores) {
magma_connection_release_semaphore(connection_, semaphore);
}
for (auto& semaphore : submits[i].signal_semaphores) {
magma_connection_release_semaphore(connection_, semaphore);
}
}
}
void ReadBufferAt(magma_buffer_t buffer, size_t size, uint32_t dword_offset,
uint32_t* result_out) {
void* vaddr;
ASSERT_TRUE(magma::MapCpuHelper(buffer, 0 /*offset*/, size, &vaddr));
*result_out = reinterpret_cast<uint32_t*>(vaddr)[dword_offset];
ASSERT_TRUE(magma::UnmapCpuHelper(vaddr, size));
}
void ClearBuffer(magma_buffer_t buffer, size_t size, uint32_t value) {
void* vaddr;
ASSERT_TRUE(magma::MapCpuHelper(buffer, 0 /*offset*/, size, &vaddr));
for (uint32_t i = 0; i < size / sizeof(uint32_t); i++) {
reinterpret_cast<uint32_t*>(vaddr)[i] = value;
}
ASSERT_TRUE(magma::UnmapCpuHelper(vaddr, size));
}
void InitBatchMemoryWrite(magma_buffer_t buffer, size_t size, uint32_t pattern,
uint64_t target_gpu_addr) {
void* vaddr;
ASSERT_TRUE(magma::MapCpuHelper(buffer, 0 /*offset*/, size, &vaddr));
memset(vaddr, 0, size);
{
auto batch_ptr = reinterpret_cast<uint32_t*>(vaddr);
*batch_ptr++ = (0x20 << 23) // command opcode: store dword
| 4 - 2; // number of dwords - 2
*batch_ptr++ = magma::lower_32_bits(target_gpu_addr);
*batch_ptr++ = magma::upper_32_bits(target_gpu_addr);
*batch_ptr++ = pattern;
*batch_ptr++ = 0xA << 23; // command opcode: batch end
}
ASSERT_TRUE(magma::UnmapCpuHelper(vaddr, size));
}
void InitBatchSemaphoreWait(magma_buffer_t buffer, size_t size, uint32_t pattern,
uint64_t target_gpu_addr) {
void* vaddr;
ASSERT_TRUE(magma::MapCpuHelper(buffer, 0 /*offset*/, size, &vaddr));
memset(vaddr, 0, size);
{
auto batch_ptr = reinterpret_cast<uint32_t*>(vaddr);
// wait for value at memory location to be > pattern
*batch_ptr++ = (0x1C << 23) // command opcode: wait for semaphore
| (1 << 15) // polling mode
| 4 - 2; // number of dwords - 2
*batch_ptr++ = pattern;
*batch_ptr++ = magma::lower_32_bits(target_gpu_addr);
*batch_ptr++ = magma::upper_32_bits(target_gpu_addr);
*batch_ptr++ = 0xA << 23; // command opcode: batch end
}
ASSERT_TRUE(magma::UnmapCpuHelper(vaddr, size));
}
void InitCommand(magma_command_descriptor* descriptor, magma_exec_command_buffer* command_buffer,
std::vector<magma_exec_resource>* exec_resources,
magma_buffer_id_t batch_buffer_id, uint64_t batch_buffer_size,
magma_buffer_id_t result_buffer_id, uint64_t result_buffer_size) {
exec_resources->clear();
exec_resources->push_back(
{.buffer_id = batch_buffer_id, .offset = 0, .length = batch_buffer_size});
exec_resources->push_back(
{.buffer_id = result_buffer_id, .offset = 0, .length = result_buffer_size});
command_buffer->resource_index = 0;
command_buffer->start_offset = 0;
descriptor->resource_count = static_cast<uint32_t>(exec_resources->size());
descriptor->command_buffer_count = 1;
descriptor->wait_semaphore_count = 0;
descriptor->signal_semaphore_count = 0;
descriptor->resources = exec_resources->data();
descriptor->command_buffers = command_buffer;
descriptor->semaphore_ids = nullptr;
descriptor->flags = 0;
}
private:
magma::TestDeviceBase base_;
magma_connection_t connection_;
uint32_t context_ids_[2] = {0};
uint64_t extra_page_count_ = 0;
uint64_t gpu_addr_ = 0x10000;
};
class TestExecuteCommandBufferCount : public TestExecuteWithCount {};
TEST_P(TestExecuteCommandBufferCount, RenderOneContext) {
MemoryWriteAndReadback(RENDER_ONLY, GetParam(), 1);
}
TEST_P(TestExecuteCommandBufferCount, VideoOneContext) {
MemoryWriteAndReadback(VIDEO_ONLY, GetParam(), 1);
}
TEST_P(TestExecuteCommandBufferCount, RenderAndVideoOneContext) {
MemoryWriteAndReadback(RENDER_AND_VIDEO_INTERLEAVED, GetParam(), 1);
}
TEST_P(TestExecuteCommandBufferCount, RenderTwoContext) {
MemoryWriteAndReadback(RENDER_ONLY, GetParam(), 2);
}
TEST_P(TestExecuteCommandBufferCount, VideoTwoContext) {
MemoryWriteAndReadback(VIDEO_ONLY, GetParam(), 2);
}
TEST_P(TestExecuteCommandBufferCount, RenderAndVideoTwoContext) {
MemoryWriteAndReadback(RENDER_AND_VIDEO_INTERLEAVED, GetParam(), 2);
}
INSTANTIATE_TEST_SUITE_P(ExecuteMemoryWriteAndReadback, TestExecuteCommandBufferCount,
::testing::Values(1000), [](testing::TestParamInfo<uint32_t> info) {
return std::to_string(info.param);
});
class TestExecuteContextCount : public TestExecuteWithCount {};
TEST_P(TestExecuteContextCount, SemaphoreWaitAndSignal) { SemaphoreWaitAndSignal(GetParam()); }
INSTANTIATE_TEST_SUITE_P(ExecuteSemaphore, TestExecuteContextCount, ::testing::Values(1, 2),
[](testing::TestParamInfo<uint32_t> info) {
return std::to_string(info.param);
});
class TestMemoryWriteEngineInterleavedPresubmitQueueing : public TestExecuteWithCount {};
TEST_P(TestMemoryWriteEngineInterleavedPresubmitQueueing, OneSemaphore) {
MemoryWriteEngineInterleavedPresubmitQueueing(GetParam(), /* semaphore_count= */ 1);
}
TEST_P(TestMemoryWriteEngineInterleavedPresubmitQueueing, ManySemaphore) {
MemoryWriteEngineInterleavedPresubmitQueueing(GetParam(), /* semaphore_count= */ 3);
}
TEST_P(TestMemoryWriteEngineInterleavedPresubmitQueueing, OneCounterSemaphore) {
constexpr bool kUseCounterSemaphore = true;
MemoryWriteEngineInterleavedPresubmitQueueing(GetParam(), /* semaphore_count= */ 1,
kUseCounterSemaphore);
}
TEST_P(TestMemoryWriteEngineInterleavedPresubmitQueueing, ManyCounterSemaphore) {
constexpr bool kUseCounterSemaphore = true;
MemoryWriteEngineInterleavedPresubmitQueueing(GetParam(), /* semaphore_count= */ 3,
kUseCounterSemaphore);
}
INSTANTIATE_TEST_SUITE_P(MemoryWriteEngineInterleavedPresubmitQueueing,
TestMemoryWriteEngineInterleavedPresubmitQueueing, ::testing::Values(2, 4),
[](testing::TestParamInfo<uint32_t> info) {
return std::to_string(info.param);
});
} // namespace