Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
ordering-table.hh
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2024 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29#include <EASTL/algorithm.h>
30#include <stdint.h>
31
33#include "psyqo/fragments.hh"
34#include "psyqo/kernel.hh"
35#include "psyqo/shared.hh"
36
37namespace psyqo {
38
39class GPU;
40
42 public:
43 static void clear(psyqo::Fragments::ChainEntry* table, size_t size);
44};
45
60template <size_t N = 4096, Safe safety = Safe::Yes>
62 public:
64
74
92 template <Fragment Frag>
93 void insert(Frag& frag, int32_t z) {
94 // Ordering tables sort individual polygons, so a packet large enough to need the oversized
95 // encoding is nonsense here and deliberately unsupported. Catch it at the definition site
96 // instead: past the chain entry, sizeof(Frag) covers the payload (plus count, on the fixed
97 // variants), so it is a conservative upper bound, and it costs nothing at runtime.
98 static_assert((sizeof(Frag) - sizeof(Fragments::ChainEntry)) / sizeof(uint32_t) <= 255,
99 "Fragment too big to be inserted into an ordering table");
100 auto* table = m_table + 1;
101 if constexpr (safety == Safe::Yes) {
102 z = eastl::clamp(z, int32_t(0), int32_t(N - 1));
103 }
104#ifdef PS1_PC_PORT
105 frag.set(table[z].next, frag.getActualFragmentSize());
106 table[z].set(&frag, 0);
107#else
108 frag.set(&table[z], frag.getActualFragmentSize());
109 table[z].head = reinterpret_cast<uint32_t>(&frag) & 0xffffff;
110#endif
111 }
112
113 // NOTE: can't use from other classes (PCGPU) otherwise
115
116 private:
117 friend class GPU;
118};
127template <Safe safety = Safe::Yes>
129 public:
130 DynamicOrderingTable(psyqo::Fragments::ChainEntry* storage, size_t buckets) : m_table(storage), m_size(buckets) {
131 if constexpr (safety == Safe::Yes) {
132 psyqo::Kernel::assert(storage && buckets > 0,
133 "DynamicOrderingTable: needs storage and at least one bucket");
134 }
135 clear();
136 }
138
142 template <Fragment Frag>
143 void insert(Frag& frag, int32_t z) {
144 static_assert((sizeof(Frag) - sizeof(Fragments::ChainEntry)) / sizeof(uint32_t) <= 255,
145 "Fragment too big to be inserted into an ordering table");
146 auto* table = m_table + 1;
147 if constexpr (safety == Safe::Yes) {
148 z = eastl::clamp(z, int32_t(0), int32_t(m_size - 1));
149 }
150#ifdef PS1_PC_PORT
151 frag.set(table[z].next, frag.getActualFragmentSize());
152 table[z].set(&frag, 0);
153#else
154 frag.set(&table[z], frag.getActualFragmentSize());
155 table[z].head = reinterpret_cast<uint32_t>(&frag) & 0xffffff;
156#endif
157 }
158 size_t size() const { return m_size; }
159
160 // NOTE: can't use from other classes (PCGPU) otherwise
162
163 private:
164 size_t m_size;
165 friend class GPU;
166};
167
168} // namespace psyqo
An ordering table whose bucket count is chosen at runtime.
Definition ordering-table.hh:128
void insert(Frag &frag, int32_t z)
Inserts a fragment into the ordering table, as OrderingTable::insert.
Definition ordering-table.hh:143
void clear()
Definition ordering-table.hh:137
size_t size() const
Definition ordering-table.hh:158
DynamicOrderingTable(psyqo::Fragments::ChainEntry *storage, size_t buckets)
Definition ordering-table.hh:130
psyqo::Fragments::ChainEntry * m_table
Definition ordering-table.hh:161
The singleton GPU class.
Definition gpu.hh:83
Definition ordering-table.hh:41
static void clear(psyqo::Fragments::ChainEntry *table, size_t size)
Definition ordering-table.cpp:29
The ordering table. Used to sort fragments before sending them to the GPU.
Definition ordering-table.hh:61
psyqo::Fragments::ChainEntry m_table[N+1]
Definition ordering-table.hh:114
void insert(Frag &frag, int32_t z)
Inserts a fragment into the ordering table.
Definition ordering-table.hh:93
OrderingTable()
Definition ordering-table.hh:63
void clear()
Clears the ordering table.
Definition ordering-table.hh:73
static int size
Definition string.h:149
#define N
Definition main.c:37
void assert(bool condition, const char *message, std::source_location location=std::source_location::current())
A simple assert macro.
Definition kernel.hh:366
Definition lua.hh:40
Definition fragments.hh:88