187 rader
6.1 KiB
C++
187 rader
6.1 KiB
C++
|
|
// MIT License
|
||
|
|
//
|
||
|
|
// Copyright (c) 2017-2025 Advanced Micro Devices, Inc.
|
||
|
|
//
|
||
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
|
// of this software and associated documentation files (the "Software"), to deal
|
||
|
|
// in the Software without restriction, including without limitation the rights
|
||
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
|
// copies of the Software, and to permit persons to whom the Software is
|
||
|
|
// furnished to do so, subject to the following conditions:
|
||
|
|
//
|
||
|
|
// The above copyright notice and this permission notice shall be included in
|
||
|
|
// all copies or substantial portions of the Software.
|
||
|
|
//
|
||
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
|
|
// THE SOFTWARE.
|
||
|
|
|
||
|
|
#pragma once
|
||
|
|
|
||
|
|
#include <cstdint>
|
||
|
|
#include <future>
|
||
|
|
#include <map>
|
||
|
|
#include <string>
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
#include "core/aql_profile_exception.h"
|
||
|
|
#include "core/aql_profile_exception.h"
|
||
|
|
#include "core/aql_profile.hpp"
|
||
|
|
|
||
|
|
namespace aql_profile {
|
||
|
|
class CommandBufferMgr {
|
||
|
|
public:
|
||
|
|
struct info_t {
|
||
|
|
uint32_t prefix_size;
|
||
|
|
uint32_t rdcmds_size;
|
||
|
|
uint32_t rd2cmds_size;
|
||
|
|
uint32_t is_rd_fetch2;
|
||
|
|
uint32_t precmds_size;
|
||
|
|
uint32_t postcmds_size;
|
||
|
|
};
|
||
|
|
|
||
|
|
CommandBufferMgr(void* ptr, const uint32_t& size) { Init(descriptor_t{ptr, size}, false); }
|
||
|
|
explicit CommandBufferMgr(const profile_t* profile) { Init(profile->command_buffer, true); }
|
||
|
|
|
||
|
|
char* GetPrefix() { return reinterpret_cast<char*>(buffer_.ptr); }
|
||
|
|
char* GetPrefix1() { return reinterpret_cast<char*>(buffer_.ptr) + sizeof(info_t); }
|
||
|
|
char* AddPrefix(const uint32_t& delta) {
|
||
|
|
const uint32_t size = Align(delta);
|
||
|
|
char* ptr = (buffer_.ptr != NULL) ? GetPrefix() + info_.prefix_size : NULL;
|
||
|
|
info_.prefix_size += delta;
|
||
|
|
buffer_.size -= (size < buffer_.size) ? size : buffer_.size;
|
||
|
|
if (buffer_.size == 0)
|
||
|
|
throw aql_profile_exc_msg("CommandBufferMgr::AddPrefix(): buffer size set to zero");
|
||
|
|
return (buffer_.size != 0) ? ptr : NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SetRdSize(const uint32_t& rd_data_size) {
|
||
|
|
const uint32_t size = Align(rd_data_size);
|
||
|
|
const bool suc = (size <= buffer_.size);
|
||
|
|
if (suc) {
|
||
|
|
info_.rdcmds_size = rd_data_size;
|
||
|
|
buffer_.size -= size;
|
||
|
|
}
|
||
|
|
if (!suc)
|
||
|
|
throw aql_profile_exc_msg("CommandBufferMgr::SetRdSize(): size set out of the buffer");
|
||
|
|
return suc;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SetRd2Size(const uint32_t& rd_data_size) {
|
||
|
|
const uint32_t size = Align(rd_data_size);
|
||
|
|
const bool suc = SetRdSize(Align(size));
|
||
|
|
if (suc) {
|
||
|
|
info_.rd2cmds_size = rd_data_size;
|
||
|
|
info_.rdcmds_size = 2 * size;
|
||
|
|
}
|
||
|
|
if (!suc)
|
||
|
|
throw aql_profile_exc_msg("CommandBufferMgr::SetRd2Size(): size set out of the buffer");
|
||
|
|
return suc;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SetPreSize(const uint32_t& pre_data_size) {
|
||
|
|
const uint32_t size = Align(pre_data_size);
|
||
|
|
const bool suc = (size <= buffer_.size);
|
||
|
|
if (suc) {
|
||
|
|
info_.precmds_size = pre_data_size;
|
||
|
|
buffer_.size -= size;
|
||
|
|
}
|
||
|
|
if (!suc)
|
||
|
|
throw aql_profile_exc_msg("CommandBufferMgr::SetPreSize(): size set out of the buffer");
|
||
|
|
return suc;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool Finalize(const uint32_t& data_size) {
|
||
|
|
bool suc = (data_size > info_.precmds_size);
|
||
|
|
if (suc) {
|
||
|
|
const uint32_t post_data_size = data_size - info_.precmds_size;
|
||
|
|
const uint32_t size = Align(post_data_size);
|
||
|
|
suc = (size <= buffer_.size);
|
||
|
|
if (suc) {
|
||
|
|
info_.postcmds_size = post_data_size;
|
||
|
|
buffer_.size -= size;
|
||
|
|
}
|
||
|
|
if (!suc)
|
||
|
|
throw aql_profile_exc_msg("CommandBufferMgr::Finalize(): postcmd size is out of cmdbuffer");
|
||
|
|
}
|
||
|
|
if (!suc) throw aql_profile_exc_msg("CommandBufferMgr::Finalize(): postcmd size is zero");
|
||
|
|
|
||
|
|
if (info_slot_) *info_slot_ = info_;
|
||
|
|
|
||
|
|
return suc;
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32_t GetSize() const { return GetEndOffset(); }
|
||
|
|
|
||
|
|
descriptor_t GetRdDescr() const {
|
||
|
|
descriptor_t descr;
|
||
|
|
descr.ptr = reinterpret_cast<char*>(buffer_.ptr) + GetRdOffset();
|
||
|
|
descr.size = info_.rdcmds_size;
|
||
|
|
return descr;
|
||
|
|
}
|
||
|
|
|
||
|
|
descriptor_t FetchRdDescr() {
|
||
|
|
descriptor_t descr;
|
||
|
|
if (info_.is_rd_fetch2 == 0) {
|
||
|
|
info_.is_rd_fetch2 = 1;
|
||
|
|
descr.ptr = reinterpret_cast<char*>(buffer_.ptr) + GetRdOffset();
|
||
|
|
} else {
|
||
|
|
descr.ptr = reinterpret_cast<char*>(buffer_.ptr) + GetRdOffset() + (info_.rdcmds_size / 2);
|
||
|
|
}
|
||
|
|
descr.size = info_.rd2cmds_size;
|
||
|
|
return descr;
|
||
|
|
}
|
||
|
|
|
||
|
|
descriptor_t GetPreDescr() const {
|
||
|
|
descriptor_t descr;
|
||
|
|
descr.ptr = reinterpret_cast<char*>(buffer_.ptr) + GetPreOffset();
|
||
|
|
descr.size = info_.precmds_size;
|
||
|
|
return descr;
|
||
|
|
}
|
||
|
|
|
||
|
|
descriptor_t GetPostDescr() const {
|
||
|
|
descriptor_t descr;
|
||
|
|
descr.ptr = reinterpret_cast<char*>(buffer_.ptr) + GetPostOffset();
|
||
|
|
descr.size = info_.postcmds_size;
|
||
|
|
return descr;
|
||
|
|
}
|
||
|
|
|
||
|
|
static uint32_t Align(const uint32_t& size) { return (size + align_mask_) & ~align_mask_; }
|
||
|
|
|
||
|
|
private:
|
||
|
|
void Init(const descriptor_t& buffer, const bool& import) {
|
||
|
|
buffer_ = buffer;
|
||
|
|
info_ = {};
|
||
|
|
info_slot_ = NULL;
|
||
|
|
|
||
|
|
uint32_t prefix_size = sizeof(info_t);
|
||
|
|
if (buffer_.ptr != NULL) {
|
||
|
|
info_slot_ = reinterpret_cast<info_t*>(GetPrefix());
|
||
|
|
if (import) {
|
||
|
|
prefix_size = info_slot_->prefix_size;
|
||
|
|
info_ = *info_slot_;
|
||
|
|
info_.prefix_size = 0;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
buffer_.size = UINT_MAX;
|
||
|
|
}
|
||
|
|
AddPrefix(prefix_size);
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32_t GetRdOffset() const { return Align(info_.prefix_size); }
|
||
|
|
uint32_t GetPreOffset() const { return GetRdOffset() + Align(info_.rdcmds_size); }
|
||
|
|
uint32_t GetPostOffset() const { return GetPreOffset() + Align(info_.precmds_size); }
|
||
|
|
uint32_t GetEndOffset() const { return GetPostOffset() + Align(info_.postcmds_size); }
|
||
|
|
|
||
|
|
static const uint32_t align_size_ = 0x100;
|
||
|
|
static const uint32_t align_mask_ = align_size_ - 1;
|
||
|
|
|
||
|
|
descriptor_t buffer_;
|
||
|
|
info_t info_;
|
||
|
|
info_t* info_slot_;
|
||
|
|
};
|
||
|
|
} // namespace aql_profile
|