-
Tobias Frisch authored
Signed-off-by:
Tobias Frisch <tfrisch@uni-koblenz.de>
Tobias Frisch authoredSigned-off-by:
Tobias Frisch <tfrisch@uni-koblenz.de>
PushConstants.hpp 3.78 KiB
#pragma once
/**
* @authors Tobias Frisch, Alexander Gauggel
* @file vkcv/PushConstants.hpp
* @brief Class to manage push constants for pipeline recording.
*/
#include <vector>
#include <vulkan/vulkan.hpp>
#include "Logger.hpp"
namespace vkcv {
/**
* @brief Class to handle push constants data per drawcall.
*/
class PushConstants {
private:
std::vector<uint8_t> m_data;
size_t m_sizePerDrawcall;
public:
template<typename T>
PushConstants() : PushConstants(sizeof(T)) {}
explicit PushConstants(size_t sizePerDrawcall) :
m_data(),
m_sizePerDrawcall(sizePerDrawcall) {}
PushConstants(const PushConstants& other) = default;
PushConstants(PushConstants&& other) = default;
~PushConstants() = default;
PushConstants& operator=(const PushConstants& other) = default;
PushConstants& operator=(PushConstants&& other) = default;
/**
* @brief Returns the size of the data that is bound
* per drawcall in bytes.
*
* @return Size of data per drawcall
*/
[[nodiscard]]
size_t getSizePerDrawcall() const {
return m_sizePerDrawcall;
}
/**
* @brief Returns the size of total data stored for
* push constants in bytes
*
* @return Total size of data
*/
[[nodiscard]]
size_t getFullSize() const {
return m_data.size();
}
/**
* @brief Returns the number of drawcalls that data
* is stored for.
*
* @return Number of drawcalls
*/
[[nodiscard]]
size_t getDrawcallCount() const {
return (m_data.size() / m_sizePerDrawcall);
}
/**
* @brief Clears the data for all drawcalls currently.
* stored.
*/
void clear() {
m_data.clear();
}
/**
* @brief Appends data for a single drawcall to the
* storage with a given type.
*
* @tparam T Type of data (must match the size per drawcall)
* @param[in] value Data to append
* @return True, if operation was successfull, otherwise false
*/
template<typename T = uint8_t>
bool appendDrawcall(const T& value) {
if (sizeof(T) != m_sizePerDrawcall) {
vkcv_log(LogLevel::WARNING, "Size (%lu) of value does not match the specified size per drawcall (%lu)",
sizeof(value), m_sizePerDrawcall);
return false;
}
const size_t offset = m_data.size();
m_data.resize(offset + sizeof(value));
std::memcpy(m_data.data() + offset, &value, sizeof(value));
return true;
}
/**
* @brief Returns the data of the drawcall by a given index
* as reference.
*
* @tparam T Type of data
* @param[in] index Index of the drawcall
* @return Drawcall data
*/
template<typename T = uint8_t>
T& getDrawcall(size_t index) {
const size_t offset = (index * m_sizePerDrawcall);
return *reinterpret_cast<T*>(m_data.data() + offset);
}
/**
* @brief Returns the data of the drawcall by a given index
* as const reference.
*
* @tparam T Type of data
* @param[in] index Index of the drawcall
* @return Drawcall data
*/
template<typename T = uint8_t>
const T& getDrawcall(size_t index) const {
const size_t offset = (index * m_sizePerDrawcall);
return *reinterpret_cast<const T*>(m_data.data() + offset);
}
/**
* @brief Returns the data of the drawcall by a given index
* as a pointer.
*
* @param[in] index Index of the drawcall
* @return Drawcall data
*/
[[nodiscard]]
const void* getDrawcallData(size_t index) const {
const size_t offset = (index * m_sizePerDrawcall);
return reinterpret_cast<const void*>(m_data.data() + offset);
}
/**
* @brief Returns the pointer to the entire drawcall data which
* might be nullptr if the data is empty.
*
* @return Pointer to the data
*/
[[nodiscard]]
const void* getData() const {
if (m_data.empty()) {
return nullptr;
} else {
return m_data.data();
}
}
};
}