blob: 1eb0da0634dd3a03b8e098f648267210959bb718 [file] [log] [blame]
// Copyright 2017 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 "msd_arm_buffer.h"
#include "gpu_mapping.h"
#include "msd.h"
#include "msd_arm_connection.h"
MsdArmBuffer::MsdArmBuffer(std::unique_ptr<magma::PlatformBuffer> platform_buf)
: platform_buf_(std::move(platform_buf))
{
}
MsdArmBuffer::~MsdArmBuffer()
{
size_t mapping_count = gpu_mappings_.size();
for (auto mapping : gpu_mappings_)
mapping->Remove();
// The weak pointer to this should already have been invalidated, so
// Remove() shouldn't be able to modify gpu_mappings_.
DASSERT(gpu_mappings_.size() == mapping_count);
}
std::unique_ptr<MsdArmBuffer> MsdArmBuffer::Import(uint32_t handle)
{
auto platform_buf = magma::PlatformBuffer::Import(handle);
if (!platform_buf)
return DRETP(nullptr, "MsdArmBuffer::Create: Could not create platform buffer from token");
return std::unique_ptr<MsdArmBuffer>(new MsdArmBuffer(std::move(platform_buf)));
}
std::unique_ptr<MsdArmBuffer> MsdArmBuffer::Create(uint64_t size, const char* name)
{
auto platform_buf = magma::PlatformBuffer::Create(size, name);
if (!platform_buf)
return DRETP(nullptr, "MsdArmBuffer::Create: Could not create platform buffer from size");
return std::unique_ptr<MsdArmBuffer>(new MsdArmBuffer(std::move(platform_buf)));
}
void MsdArmBuffer::AddMapping(GpuMapping* mapping)
{
DASSERT(!gpu_mappings_.count(mapping));
gpu_mappings_.insert(mapping);
}
void MsdArmBuffer::RemoveMapping(GpuMapping* mapping)
{
DASSERT(gpu_mappings_.count(mapping));
gpu_mappings_.erase(mapping);
}
bool MsdArmBuffer::SetCommittedPages(uint64_t start_page, uint64_t page_count)
{
if ((start_page + page_count) * PAGE_SIZE > platform_buffer()->size())
return DRETF(false, "invalid parameters start_page %lu page_count %lu\n", start_page,
page_count);
start_committed_pages_ = start_page;
committed_page_count_ = page_count;
bool success = true;
for (auto& mapping : gpu_mappings_) {
if (!mapping->UpdateCommittedMemory())
success = false;
}
return success;
}
bool MsdArmBuffer::EnsureRegionFlushed(uint64_t start_bytes, uint64_t end_bytes)
{
DASSERT(end_bytes >= start_bytes);
DASSERT(flushed_region_end_bytes_ >= flushed_region_start_bytes_);
if (start_bytes < flushed_region_start_bytes_) {
if (!platform_buf_->CleanCache(start_bytes, flushed_region_start_bytes_ - start_bytes,
false))
return DRETF(false, "CleanCache of start failed");
flushed_region_start_bytes_ = start_bytes;
}
if (end_bytes > flushed_region_end_bytes_) {
bool region_exists = flushed_region_end_bytes_ != 0;
uint64_t flush_start;
if (region_exists) {
flush_start = flushed_region_end_bytes_;
} else {
flush_start = start_bytes;
flushed_region_start_bytes_ = flush_start;
}
if (!platform_buf_->CleanCache(flush_start, end_bytes - flush_start, false))
return DRETF(false, "CleanCache of end failed");
flushed_region_end_bytes_ = end_bytes;
}
return true;
}
//////////////////////////////////////////////////////////////////////////////
msd_buffer_t* msd_buffer_import(uint32_t handle)
{
auto buffer = MsdArmBuffer::Import(handle);
if (!buffer)
return DRETP(nullptr, "MsdArmBuffer::Create failed");
return new MsdArmAbiBuffer(std::move(buffer));
}
void msd_buffer_destroy(msd_buffer_t* buf) { delete MsdArmAbiBuffer::cast(buf); }