blob: 8a45468e8c63b505d5e5df98e9ae9b679bb73dd0 [file] [log] [blame]
// Copyright 2016 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 "mock/mock_address_space.h"
#include "mock/mock_bus_mapper.h"
#include "msd_intel_buffer.h"
#include "gtest/gtest.h"
#include <thread>
class TestMsdIntelBuffer {
public:
class AddressSpaceOwner : public AddressSpace::Owner {
public:
virtual ~AddressSpaceOwner() = default;
magma::PlatformBusMapper* GetBusMapper() override { return &bus_mapper_; }
private:
MockBusMapper bus_mapper_;
};
static void CreateAndDestroy()
{
std::unique_ptr<MsdIntelBuffer> buffer;
uint64_t size;
buffer = MsdIntelBuffer::Create(size = 0, "test");
EXPECT_EQ(buffer, nullptr);
buffer = MsdIntelBuffer::Create(size = 100, "test");
EXPECT_NE(buffer, nullptr);
EXPECT_GE(buffer->platform_buffer()->size(), size);
buffer = MsdIntelBuffer::Create(size = 10000, "test");
EXPECT_NE(buffer, nullptr);
EXPECT_GE(buffer->platform_buffer()->size(), size);
}
static void MapGpu()
{
uint64_t base = PAGE_SIZE;
uint64_t size = PAGE_SIZE * 10;
auto address_space_owner = std::make_unique<AddressSpaceOwner>();
auto address_space =
std::make_shared<MockAddressSpace>(address_space_owner.get(), base, size);
std::unique_ptr<MsdIntelBuffer> buffer(MsdIntelBuffer::Create(PAGE_SIZE, "test"));
ASSERT_NE(buffer, nullptr);
auto mapping = AddressSpace::MapBufferGpu(address_space, std::move(buffer));
ASSERT_NE(mapping, nullptr);
gpu_addr_t gpu_addr = mapping->gpu_addr();
EXPECT_TRUE(address_space->is_allocated(gpu_addr));
EXPECT_FALSE(address_space->is_clear(gpu_addr));
mapping.reset();
EXPECT_FALSE(address_space->is_allocated(gpu_addr));
EXPECT_TRUE(address_space->is_clear(gpu_addr));
}
static void SharedMapping(uint64_t size)
{
auto address_space_owner = std::make_unique<AddressSpaceOwner>();
auto address_space = std::make_shared<MockAddressSpace>(address_space_owner.get(), 0,
magma::round_up(size, PAGE_SIZE));
ASSERT_EQ(address_space->type(), ADDRESS_SPACE_PPGTT);
std::shared_ptr<MsdIntelBuffer> buffer(MsdIntelBuffer::Create(size, "test"));
ASSERT_NE(buffer, nullptr);
EXPECT_EQ(1u, buffer.use_count());
auto mapping = AddressSpace::GetSharedGpuMapping(address_space, buffer, 0,
buffer->platform_buffer()->size());
EXPECT_EQ(2u, buffer.use_count());
EXPECT_EQ(2u, mapping.use_count());
auto mapping2 = AddressSpace::GetSharedGpuMapping(address_space, buffer, 0,
buffer->platform_buffer()->size());
EXPECT_EQ(mapping, mapping2);
EXPECT_EQ(2u, buffer.use_count());
EXPECT_EQ(3u, mapping.use_count());
mapping.reset();
mapping2.reset();
// Mapping retained in the address space
EXPECT_EQ(2u, buffer.use_count());
std::vector<std::shared_ptr<GpuMapping>> mappings;
address_space->ReleaseBuffer(buffer->platform_buffer(), &mappings);
EXPECT_EQ(1u, mappings.size());
EXPECT_EQ(2u, buffer.use_count());
mappings.clear();
EXPECT_EQ(1u, buffer.use_count());
}
static void OverlappedMapping()
{
auto address_space_owner = std::make_unique<AddressSpaceOwner>();
auto address_space =
std::make_shared<MockAddressSpace>(address_space_owner.get(), 0, PAGE_SIZE * 10);
ASSERT_EQ(address_space->type(), ADDRESS_SPACE_PPGTT);
constexpr uint32_t kBufferSize = PAGE_SIZE * 6;
std::shared_ptr<MsdIntelBuffer> buffer(MsdIntelBuffer::Create(kBufferSize, "test"));
ASSERT_NE(buffer, nullptr);
EXPECT_EQ(1u, buffer.use_count());
std::shared_ptr<GpuMapping> mapping_low =
AddressSpace::GetSharedGpuMapping(address_space, buffer, 0, kBufferSize / 2);
ASSERT_NE(mapping_low, nullptr);
EXPECT_EQ(2u, buffer.use_count());
std::shared_ptr<GpuMapping> mapping_high = AddressSpace::GetSharedGpuMapping(
address_space, buffer, kBufferSize / 2, kBufferSize / 2);
ASSERT_NE(mapping_high, nullptr);
EXPECT_EQ(3u, buffer.use_count());
// not the same mapping
EXPECT_NE(mapping_low.get(), mapping_high.get());
std::shared_ptr<GpuMapping> mapping_full =
AddressSpace::GetSharedGpuMapping(address_space, buffer, 0, kBufferSize);
ASSERT_NE(mapping_full, nullptr);
EXPECT_NE(mapping_full.get(), mapping_low.get());
EXPECT_NE(mapping_full.get(), mapping_high.get());
EXPECT_EQ(4u, buffer.use_count());
mapping_low = AddressSpace::GetSharedGpuMapping(address_space, buffer, 0, kBufferSize / 2);
ASSERT_NE(mapping_low, nullptr);
EXPECT_NE(mapping_low.get(), mapping_full.get());
mapping_high = AddressSpace::GetSharedGpuMapping(
address_space, buffer, kBufferSize - kBufferSize / 2, kBufferSize / 2);
ASSERT_NE(mapping_high, nullptr);
EXPECT_NE(mapping_high.get(), mapping_full.get());
}
};
TEST(MsdIntelBuffer, CreateAndDestroy) { TestMsdIntelBuffer::CreateAndDestroy(); }
TEST(MsdIntelBuffer, MapGpu) { TestMsdIntelBuffer::MapGpu(); }
TEST(MsdIntelBuffer, SharedMapping)
{
TestMsdIntelBuffer::SharedMapping(0x400);
TestMsdIntelBuffer::SharedMapping(0x1000);
TestMsdIntelBuffer::SharedMapping(0x16000);
}
TEST(MsdIntelBuffer, OverlappedMapping) { TestMsdIntelBuffer::OverlappedMapping(); }