2022-01-13 09:26:59 -08:00
|
|
|
// Copyright (c) 2022- PPSSPP Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-01-14 20:19:32 -08:00
|
|
|
#include <atomic>
|
2022-01-13 22:17:12 -08:00
|
|
|
#include "Common/Log.h"
|
2022-01-13 09:26:59 -08:00
|
|
|
#include "GPU/Software/Rasterizer.h"
|
|
|
|
|
2022-01-13 22:17:12 -08:00
|
|
|
struct BinWaitable;
|
|
|
|
|
2022-01-13 19:07:41 -08:00
|
|
|
enum class BinItemType {
|
|
|
|
TRIANGLE,
|
|
|
|
CLEAR_RECT,
|
|
|
|
SPRITE,
|
|
|
|
LINE,
|
|
|
|
POINT,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BinCoords {
|
|
|
|
int x1;
|
|
|
|
int y1;
|
|
|
|
int x2;
|
|
|
|
int y2;
|
2022-01-13 22:17:12 -08:00
|
|
|
|
|
|
|
bool Invalid() const {
|
|
|
|
return x2 < x1 || y2 < y1;
|
|
|
|
}
|
|
|
|
|
|
|
|
BinCoords Intersect(const BinCoords &range) const;
|
2022-01-13 19:07:41 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BinItem {
|
|
|
|
BinItemType type;
|
|
|
|
int stateIndex;
|
|
|
|
BinCoords range;
|
|
|
|
VertexData v0;
|
|
|
|
VertexData v1;
|
|
|
|
VertexData v2;
|
|
|
|
};
|
|
|
|
|
2022-01-13 22:17:12 -08:00
|
|
|
template <typename T, size_t N>
|
|
|
|
struct BinQueue {
|
|
|
|
BinQueue() {
|
|
|
|
items_ = new T[N];
|
|
|
|
Reset();
|
|
|
|
}
|
|
|
|
~BinQueue() {
|
|
|
|
delete [] items_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Reset() {
|
|
|
|
head_ = 0;
|
|
|
|
tail_ = 0;
|
|
|
|
size_ = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Push(const T &item) {
|
2022-01-15 21:59:23 -08:00
|
|
|
_dbg_assert_(size_ < N - 1);
|
2022-01-13 22:17:12 -08:00
|
|
|
size_t i = tail_++;
|
2022-01-15 00:02:31 -08:00
|
|
|
if (i + 1 == N)
|
|
|
|
tail_ -= N;
|
2022-01-13 22:17:12 -08:00
|
|
|
items_[i] = item;
|
2022-01-14 20:19:32 -08:00
|
|
|
size_++;
|
2022-01-13 22:17:12 -08:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
T Pop() {
|
2022-01-15 00:02:31 -08:00
|
|
|
_dbg_assert_(!Empty());
|
2022-01-13 22:17:12 -08:00
|
|
|
size_t i = head_++;
|
2022-01-15 00:02:31 -08:00
|
|
|
if (i + 1 == N)
|
|
|
|
head_ -= N;
|
2022-01-14 20:19:32 -08:00
|
|
|
T item = items_[i];
|
2022-01-13 22:17:12 -08:00
|
|
|
size_--;
|
2022-01-14 20:19:32 -08:00
|
|
|
return item;
|
2022-01-13 22:17:12 -08:00
|
|
|
}
|
|
|
|
|
2022-01-15 18:43:44 -08:00
|
|
|
// Only safe if you're the only one reading.
|
|
|
|
T &PeekNext() {
|
|
|
|
_dbg_assert_(!Empty());
|
|
|
|
return items_[head_];
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkipNext() {
|
|
|
|
_dbg_assert_(!Empty());
|
|
|
|
size_t i = head_++;
|
|
|
|
if (i + 1 == N)
|
|
|
|
head_ -= N;
|
|
|
|
size_--;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only safe if you're the only one writing.
|
|
|
|
T &PeekPush() {
|
2022-01-15 21:59:23 -08:00
|
|
|
_dbg_assert_(size_ < N - 1);
|
2022-01-15 18:43:44 -08:00
|
|
|
return items_[tail_];
|
|
|
|
}
|
|
|
|
|
|
|
|
void PushPeeked() {
|
2022-01-15 21:59:23 -08:00
|
|
|
_dbg_assert_(size_ < N - 1);
|
2022-01-15 18:43:44 -08:00
|
|
|
size_t i = tail_++;
|
|
|
|
if (i + 1 == N)
|
|
|
|
tail_ -= N;
|
|
|
|
size_++;
|
|
|
|
}
|
|
|
|
|
2022-01-13 22:17:12 -08:00
|
|
|
size_t Size() const {
|
|
|
|
return size_;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Full() const {
|
2022-01-15 21:59:23 -08:00
|
|
|
return size_ == N - 1;
|
2022-01-13 22:17:12 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Empty() const {
|
|
|
|
return size_ == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
T &operator[](size_t index) {
|
|
|
|
return items_[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
const T &operator[](size_t index) const {
|
|
|
|
return items_[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
T *items_ = nullptr;
|
2022-01-14 20:19:32 -08:00
|
|
|
std::atomic<size_t> head_;
|
|
|
|
std::atomic<size_t> tail_ ;
|
|
|
|
std::atomic<size_t> size_;
|
2022-01-13 22:17:12 -08:00
|
|
|
};
|
|
|
|
|
2022-01-15 23:12:03 -08:00
|
|
|
union BinClut {
|
|
|
|
uint8_t readable[1024];
|
|
|
|
};
|
|
|
|
|
2022-01-13 09:26:59 -08:00
|
|
|
class BinManager {
|
|
|
|
public:
|
2022-01-13 19:07:41 -08:00
|
|
|
BinManager();
|
2022-01-13 22:17:12 -08:00
|
|
|
~BinManager();
|
2022-01-13 19:07:41 -08:00
|
|
|
|
|
|
|
void UpdateState();
|
2022-01-15 23:12:03 -08:00
|
|
|
void UpdateClut(void *src);
|
2022-01-13 09:26:59 -08:00
|
|
|
|
|
|
|
const Rasterizer::RasterizerState &State() {
|
2022-01-13 22:17:12 -08:00
|
|
|
return states_[stateIndex_];
|
2022-01-13 09:26:59 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void AddTriangle(const VertexData &v0, const VertexData &v1, const VertexData &v2);
|
|
|
|
void AddClearRect(const VertexData &v0, const VertexData &v1);
|
|
|
|
void AddSprite(const VertexData &v0, const VertexData &v1);
|
|
|
|
void AddLine(const VertexData &v0, const VertexData &v1);
|
|
|
|
void AddPoint(const VertexData &v0);
|
|
|
|
|
2022-01-13 22:17:12 -08:00
|
|
|
void Drain();
|
2022-01-13 09:26:59 -08:00
|
|
|
void Flush();
|
|
|
|
|
|
|
|
private:
|
2022-01-14 20:19:32 -08:00
|
|
|
static constexpr int MAX_POSSIBLE_TASKS = 64;
|
|
|
|
|
2022-01-15 23:12:03 -08:00
|
|
|
BinQueue<Rasterizer::RasterizerState, 64> states_;
|
2022-01-13 19:07:41 -08:00
|
|
|
int stateIndex_;
|
2022-01-15 23:12:03 -08:00
|
|
|
BinQueue<BinClut, 64> cluts_;
|
|
|
|
int clutIndex_;
|
2022-01-13 19:07:41 -08:00
|
|
|
BinCoords scissor_;
|
2022-01-13 22:17:12 -08:00
|
|
|
BinQueue<BinItem, 1024> queue_;
|
2022-01-13 19:07:41 -08:00
|
|
|
BinCoords queueRange_;
|
|
|
|
|
2022-01-13 22:17:12 -08:00
|
|
|
int maxTasks_ = 1;
|
|
|
|
bool tasksSplit_ = false;
|
|
|
|
std::vector<BinCoords> taskRanges_;
|
2022-01-14 20:19:32 -08:00
|
|
|
BinQueue<BinItem, 1024> taskQueues_[MAX_POSSIBLE_TASKS];
|
|
|
|
std::atomic<bool> taskStatus_[MAX_POSSIBLE_TASKS];
|
2022-01-13 22:17:12 -08:00
|
|
|
BinWaitable *waitable_ = nullptr;
|
|
|
|
|
2022-01-13 19:07:41 -08:00
|
|
|
BinCoords Scissor(BinCoords range);
|
|
|
|
BinCoords Range(const VertexData &v0, const VertexData &v1, const VertexData &v2);
|
|
|
|
BinCoords Range(const VertexData &v0, const VertexData &v1);
|
|
|
|
BinCoords Range(const VertexData &v0);
|
|
|
|
void Expand(const BinCoords &range);
|
2022-01-13 09:26:59 -08:00
|
|
|
};
|