14 #include "smmintrin.h"
16 #include <forward_list>
21 #ifdef POINTER_IS_64BIT
23 # define LOAD_128 _mm_load_si128
25 # define LOAD_128 _mm_loadu_si128
29 void ViewportSortParentSpritesSSE41(ParentSpriteToSortVector *psdv)
31 if (psdv->size() < 2)
return;
33 const __m128i mask_ptest = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0);
42 const uint32_t ORDER_COMPARED = UINT32_MAX;
43 const uint32_t ORDER_RETURNED = UINT32_MAX - 1;
44 std::stack<ParentSpriteToDraw *> sprite_order;
45 uint32_t next_order = 0;
47 std::forward_list<std::pair<int64_t, ParentSpriteToDraw *>> sprite_list;
50 for (
auto p = psdv->rbegin(); p != psdv->rend(); p++) {
51 sprite_list.emplace_front((*p)->xmin + (*p)->ymin, *p);
52 sprite_order.push(*p);
53 (*p)->order = next_order++;
58 std::vector<ParentSpriteToDraw *> preceding;
59 auto preceding_prev = sprite_list.begin();
60 auto out = psdv->begin();
62 while (!sprite_order.empty()) {
64 auto s = sprite_order.top();
68 if (s->order == ORDER_RETURNED)
continue;
71 if (s->order == ORDER_COMPARED) {
73 s->order = ORDER_RETURNED;
87 auto ssum = std::max(s->xmax, s->xmin) + std::max(s->ymax, s->ymin);
88 auto prev = sprite_list.before_begin();
89 auto x = sprite_list.begin();
90 while (x != sprite_list.end() && ((*x).first <= ssum)) {
94 x = sprite_list.erase_after(prev);
102 __m128i s_max = LOAD_128((__m128i*) &s->xmax);
103 __m128i p_min = LOAD_128((__m128i*) &p->xmin);
104 __m128i r1 = _mm_cmplt_epi32(s_max, p_min);
105 if (!_mm_testz_si128(mask_ptest, r1))
111 __m128i s_min = LOAD_128((__m128i*) &s->xmin);
112 __m128i p_max = LOAD_128((__m128i*) &p->xmax);
113 __m128i r2 = _mm_cmplt_epi32(p_max, s_min);
114 if (_mm_testz_si128(mask_ptest, r2)) {
121 if (s->xmin + s->xmax + s->ymin + s->ymax + s->zmin + s->zmax <=
122 p->xmin + p->xmax + p->ymin + p->ymax + p->zmin + p->zmax) {
127 preceding.push_back(p);
128 preceding_prev = p_prev;
131 if (preceding.empty()) {
134 s->order = ORDER_RETURNED;
139 if (preceding.size() == 1) {
140 auto p = preceding[0];
142 if (p->xmax <= s->xmax && p->ymax <= s->ymax && p->zmax <= s->zmax) {
143 p->order = ORDER_RETURNED;
144 s->order = ORDER_RETURNED;
145 sprite_list.erase_after(preceding_prev);
154 return a->order > b->order;
157 s->order = ORDER_COMPARED;
158 sprite_order.push(s);
160 for (
auto p: preceding) {
161 p->order = next_order++;
162 sprite_order.push(p);
172 bool ViewportSortParentSpritesSSE41Checker()
bool HasCPUIDFlag(uint type, uint index, uint bit)
Check whether the current CPU has the given flag.
Functions related to CPU specific instructions.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
Parent sprite that should be drawn.
Types related to sprite sorting.