3#include <tess/core/shape.h>
4#include <tess/storage/chunk_page.h>
23enum class GpuFieldFormat : std::uint8_t {
37template <
typename Value>
38[[nodiscard]]
constexpr auto field_format() noexcept -> GpuFieldFormat {
42 static_assert(std::is_integral_v<Value> || std::is_same_v<Value, float>,
43 "GPU mirrors support integral and float32 field values only");
44 if constexpr (std::is_same_v<Value, float>) {
45 return GpuFieldFormat::F32;
46 }
else if constexpr (std::is_signed_v<Value>) {
47 if constexpr (
sizeof(Value) == 1) {
48 return GpuFieldFormat::I8;
49 }
else if constexpr (
sizeof(Value) == 2) {
50 return GpuFieldFormat::I16;
51 }
else if constexpr (
sizeof(Value) == 4) {
52 return GpuFieldFormat::I32;
54 return GpuFieldFormat::I64;
57 if constexpr (
sizeof(Value) == 1) {
58 return GpuFieldFormat::U8;
59 }
else if constexpr (
sizeof(Value) == 2) {
60 return GpuFieldFormat::U16;
61 }
else if constexpr (
sizeof(Value) == 4) {
62 return GpuFieldFormat::U32;
64 return GpuFieldFormat::U64;
79 std::uint32_t field_index = 0;
80 GpuFieldFormat format = GpuFieldFormat::U8;
81 std::uint32_t value_bytes = 0;
82 std::uint64_t tiles_per_chunk = 0;
83 std::uint64_t bytes_per_chunk = 0;
84 std::uint64_t chunk_count = 0;
88 return chunk_count == 0 ||
90 std::numeric_limits<std::uint64_t>::max() / chunk_count;
100 [[nodiscard]]
constexpr auto total_bytes() const noexcept -> std::uint64_t {
102 : std::numeric_limits<std::uint64_t>::max();
111template <
typename World,
typename Tag>
112[[nodiscard]]
constexpr auto field_mirror_desc() noexcept -> FieldMirrorDesc {
113 using Schema =
typename World::schema_type;
114 using Value =
typename Schema::template value_type<Tag>;
122 constexpr auto kMaxBytes = ~std::uint64_t{0};
123 static_assert(
sizeof(Value) <= kMaxBytes / Traits::local_tile_count,
124 "per-chunk mirror bytes must fit std::uint64_t");
126 Traits::chunk_count <= 1 || Traits::local_tile_count *
sizeof(Value) <=
127 kMaxBytes / Traits::chunk_count,
128 "chunk-key-major mirror byte size must fit std::uint64_t");
129 FieldMirrorDesc desc;
130 desc.field_index =
static_cast<std::uint32_t
>(Schema::template index<Tag>);
131 desc.format = detail::field_format<Value>();
132 desc.value_bytes =
static_cast<std::uint32_t
>(
sizeof(Value));
133 desc.tiles_per_chunk = Traits::local_tile_count;
134 desc.bytes_per_chunk = Traits::local_tile_count *
sizeof(Value);
135 desc.chunk_count = Traits::chunk_count;
147 std::uint32_t field_index = 0;
148 std::uint64_t buffer_offset = 0;
149 std::uint64_t byte_size = 0;
150 const void* data =
nullptr;
155 std::uint64_t key = 0;
156 std::uint64_t generation = 0;
167template <
typename Tag,
typename World>
168[[nodiscard]]
auto upload_desc(
const World& world,
ChunkKey chunk_key)
noexcept
170 const auto span = world.template field_span<Tag>(chunk_key);
171 constexpr auto desc = field_mirror_desc<World, Tag>();
173 upload.chunk_key = chunk_key;
174 upload.field_index = desc.field_index;
175 upload.buffer_offset = chunk_key.value * desc.bytes_per_chunk;
176 upload.byte_size = span.size_bytes();
177 upload.data = span.data();
184 std::uint32_t input_field_index = 0;
185 std::uint64_t chunk_count = 0;
186 std::uint32_t workgroups_per_chunk = 1;
190enum class ReadbackPolicy : std::uint8_t {
202 ReadbackPolicy policy = ReadbackPolicy::None;
203 std::uint64_t byte_size = 0;
Definition descriptors.h:182
Definition descriptors.h:78
constexpr auto total_bytes_fits() const noexcept -> bool
Definition descriptors.h:87
constexpr auto total_bytes() const noexcept -> std::uint64_t
Definition descriptors.h:100
Definition descriptors.h:154
Definition descriptors.h:200
Definition descriptors.h:145