blob: 9daac7c90d1afc33561ecde848fe16e4ffb01443 [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.
#ifndef SRC_GRAPHICS_MAGMA_LIB_MAGMA_SERVICE_MOCK_MOCK_MSD_H_
#define SRC_GRAPHICS_MAGMA_LIB_MAGMA_SERVICE_MOCK_MOCK_MSD_H_
#include <lib/magma/platform/platform_buffer.h>
#include <lib/magma/platform/platform_semaphore.h>
#include <lib/magma/util/macros.h>
#include <lib/magma_service/msd.h>
#include <lib/magma_service/msd_defs.h>
#include <lib/sync/cpp/completion.h>
#include <iterator>
#include <memory>
#include <vector>
// These classes contain default implementations of msd_device_t functionality.
// To override a specific function to contain test logic, inherit from the
// desired class, override the desired function, and pass as the msd_abi object
class MsdMockBuffer : public msd::Buffer {
public:
explicit MsdMockBuffer(std::unique_ptr<magma::PlatformBuffer> platform_buf)
: platform_buf_(std::move(platform_buf)) {}
~MsdMockBuffer() override;
static MsdMockBuffer* cast(msd::Buffer* buf) {
MAGMA_DASSERT(buf);
auto buffer = static_cast<MsdMockBuffer*>(buf);
MAGMA_DASSERT(buffer->magic_ == kMagic);
return buffer;
}
magma::PlatformBuffer* platform_buffer() { return platform_buf_.get(); }
private:
std::unique_ptr<magma::PlatformBuffer> platform_buf_;
static const uint32_t kMagic = 0x6d6b6266; // "mkbf" (Mock Buffer)
uint32_t magic_ = kMagic;
};
class MsdMockConnection;
class MsdMockContext : public msd::Context {
public:
explicit MsdMockContext(MsdMockConnection* connection) : connection_(connection) {
magic_ = kMagic;
}
~MsdMockContext() override;
magma_status_t MsdExecuteCommandBufferWithResources(msd::magma_command_buffer* command_buffer,
magma_exec_resource* exec_resources,
msd::Buffer** buffers,
msd::Semaphore** wait_semaphores,
msd::Semaphore** signal_semaphores) override {
last_submitted_exec_resources_.clear();
for (uint32_t i = 0; i < command_buffer->resource_count; i++) {
last_submitted_exec_resources_.push_back(MsdMockBuffer::cast(buffers[i]));
}
return MAGMA_STATUS_OK;
}
static MsdMockContext* cast(msd::Context* ctx) {
MAGMA_DASSERT(ctx);
auto context = static_cast<MsdMockContext*>(ctx);
MAGMA_DASSERT(context->magic_ == kMagic);
return context;
}
std::vector<MsdMockBuffer*>& last_submitted_exec_resources() {
return last_submitted_exec_resources_;
}
private:
std::vector<MsdMockBuffer*> last_submitted_exec_resources_;
MsdMockConnection* connection_;
static const uint32_t kMagic = 0x6d6b6378; // "mkcx" (Mock Context)
uint32_t magic_ = kMagic;
};
class MsdMockConnection : public msd::Connection {
public:
MsdMockConnection() { magic_ = kMagic; }
~MsdMockConnection() override {}
std::unique_ptr<msd::Context> MsdCreateContext() override {
return std::make_unique<MsdMockContext>(this);
}
virtual void DestroyContext(MsdMockContext* ctx) {}
magma_status_t MsdMapBuffer(msd::Buffer& buffer, uint64_t gpu_va, uint64_t offset,
uint64_t length, uint64_t flags) override {
return MAGMA_STATUS_OK;
}
magma_status_t MsdUnmapBuffer(msd::Buffer& buffer, uint64_t gpu_va) override {
return MAGMA_STATUS_OK;
}
magma_status_t MsdBufferRangeOp(msd::Buffer& buffer, uint32_t options, uint64_t start_offset,
uint64_t length) override {
return MAGMA_STATUS_OK;
}
magma_status_t MsdCreatePerformanceCounterBufferPool(
uint64_t pool_id, std::unique_ptr<msd::PerfCountPool>* pool_out) override;
magma_status_t MsdReleasePerformanceCounterBufferPool(
std::unique_ptr<msd::PerfCountPool> pool) override;
magma_status_t MsdAddPerformanceCounterBufferOffsetToPool(msd::PerfCountPool& pool,
msd::Buffer& buffer, uint64_t buffer_id,
uint64_t buffer_offset,
uint64_t buffer_size) override {
return MAGMA_STATUS_OK;
}
magma_status_t MsdRemovePerformanceCounterBufferFromPool(msd::PerfCountPool& pool,
msd::Buffer& buffer) override {
return MAGMA_STATUS_OK;
}
magma_status_t MsdDumpPerformanceCounters(msd::PerfCountPool& pool,
uint32_t trigger_id) override {
return MAGMA_STATUS_OK;
}
private:
static const uint32_t kMagic = 0x6d6b636e; // "mkcn" (Mock Connection)
uint32_t magic_ = kMagic;
};
class MsdMockSemaphore : public msd::Semaphore {
public:
explicit MsdMockSemaphore(std::unique_ptr<magma::PlatformSemaphore> semaphore)
: semaphore_(std::move(semaphore)) {}
~MsdMockSemaphore() override = default;
zx_koid_t GetKoid() { return semaphore_->id(); }
private:
std::unique_ptr<magma::PlatformSemaphore> semaphore_;
};
class MsdMockDevice : public msd::Device {
public:
MsdMockDevice() { magic_ = kMagic; }
~MsdMockDevice() override = default;
void MsdSetMemoryPressureLevel(msd::MagmaMemoryPressureLevel level) override;
magma_status_t MsdQuery(uint64_t id, zx::vmo* result_buffer_out, uint64_t* result_out) override;
magma_status_t MsdGetIcdList(std::vector<msd::MsdIcdInfo>* icd_info_out) override;
std::unique_ptr<msd::Connection> MsdOpen(msd::msd_client_id_t client_id) override {
return std::make_unique<MsdMockConnection>();
}
virtual uint32_t GetDeviceId() { return 0; }
void WaitForMemoryPressureSignal();
msd::MagmaMemoryPressureLevel memory_pressure_level() const {
std::lock_guard lock(level_mutex_);
return memory_pressure_level_;
}
private:
static const uint32_t kMagic = 0x6d6b6476; // "mkdv" (Mock Device)
uint32_t magic_ = kMagic;
mutable std::mutex level_mutex_;
msd::MagmaMemoryPressureLevel memory_pressure_level_ = msd::MAGMA_MEMORY_PRESSURE_LEVEL_NORMAL;
libsync::Completion completion_;
};
class MsdMockDriver : public msd::Driver {
public:
MsdMockDriver() { magic_ = kMagic; }
~MsdMockDriver() override = default;
std::unique_ptr<msd::Device> MsdCreateDevice(msd::DeviceHandle* device_data) override {
return std::make_unique<MsdMockDevice>();
}
std::unique_ptr<msd::Buffer> MsdImportBuffer(zx::vmo vmo, uint64_t client_id) override;
magma_status_t MsdImportSemaphore(zx::handle handle, uint64_t client_id, uint64_t flags,
std::unique_ptr<msd::Semaphore>* out) override;
static MsdMockDriver* cast(Driver* drv) {
MAGMA_DASSERT(drv);
auto driver = static_cast<MsdMockDriver*>(drv);
MAGMA_DASSERT(driver->magic_ == kMagic);
return driver;
}
private:
static const uint32_t kMagic = 0x6d6b6472; // "mkdr" (Mock Driver)
uint32_t magic_ = kMagic;
};
// There is no buffermanager concept in the msd abi right now, so this class is
// for testing purposes only, making it a little different than the other
// classes in this header
class MsdMockBufferManager {
public:
MsdMockBufferManager() = default;
virtual ~MsdMockBufferManager() = default;
virtual std::unique_ptr<MsdMockBuffer> CreateBuffer(zx::vmo handle, uint64_t client_id) {
auto platform_buf = magma::PlatformBuffer::Import(std::move(handle));
platform_buf->set_local_id(client_id);
return std::make_unique<MsdMockBuffer>(std::move(platform_buf));
}
virtual void DestroyBuffer(MsdMockBuffer* buf) {}
class ScopedMockBufferManager {
public:
explicit ScopedMockBufferManager(std::unique_ptr<MsdMockBufferManager> bufmgr) {
SetTestBufferManager(std::move(bufmgr));
}
~ScopedMockBufferManager() { SetTestBufferManager(nullptr); }
MsdMockBufferManager* get();
};
private:
static void SetTestBufferManager(std::unique_ptr<MsdMockBufferManager> bufmgr);
};
#endif