softgpu: Calc flags on state as we queue verts.

Might be some other ways, like doing this directly in a vertex reader.
Also am thinking about doing things regarding UVs or positions.

Flags not yet used, keeping separate for perf checks.
This commit is contained in:
Unknown W. Brackets 2022-12-02 21:27:22 -08:00
parent a04b7cf3b3
commit 6bd0eec54d
3 changed files with 47 additions and 0 deletions

View File

@ -388,6 +388,7 @@ void BinManager::AddTriangle(const VertexData &v0, const VertexData &v1, const V
if (queue_.Full())
Drain();
queue_.Push(BinItem{ BinItemType::TRIANGLE, stateIndex_, range, v0, v1, v2 });
CalculateRasterStateFlags(&states_[stateIndex_], v0, v1, v2);
Expand(range);
}
@ -399,6 +400,7 @@ void BinManager::AddClearRect(const VertexData &v0, const VertexData &v1) {
if (queue_.Full())
Drain();
queue_.Push(BinItem{ BinItemType::CLEAR_RECT, stateIndex_, range, v0, v1 });
CalculateRasterStateFlags(&states_[stateIndex_], v0, v1, true);
Expand(range);
}
@ -410,6 +412,7 @@ void BinManager::AddRect(const VertexData &v0, const VertexData &v1) {
if (queue_.Full())
Drain();
queue_.Push(BinItem{ BinItemType::RECT, stateIndex_, range, v0, v1 });
CalculateRasterStateFlags(&states_[stateIndex_], v0, v1, true);
Expand(range);
}
@ -421,6 +424,7 @@ void BinManager::AddSprite(const VertexData &v0, const VertexData &v1) {
if (queue_.Full())
Drain();
queue_.Push(BinItem{ BinItemType::SPRITE, stateIndex_, range, v0, v1 });
CalculateRasterStateFlags(&states_[stateIndex_], v0, v1, true);
Expand(range);
}
@ -432,6 +436,7 @@ void BinManager::AddLine(const VertexData &v0, const VertexData &v1) {
if (queue_.Full())
Drain();
queue_.Push(BinItem{ BinItemType::LINE, stateIndex_, range, v0, v1 });
CalculateRasterStateFlags(&states_[stateIndex_], v0, v1, false);
Expand(range);
}
@ -443,6 +448,7 @@ void BinManager::AddPoint(const VertexData &v0) {
if (queue_.Full())
Drain();
queue_.Push(BinItem{ BinItemType::POINT, stateIndex_, range, v0 });
CalculateRasterStateFlags(&states_[stateIndex_], v0);
Expand(range);
}

View File

@ -155,6 +155,33 @@ void ComputeRasterizerState(RasterizerState *state, std::function<void()> flushF
#endif
}
static inline void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0, bool useColor) {
if (useColor) {
if ((v0.color0 & 0x00FFFFFF) != 0x00FFFFFF)
state->flags |= RasterizerStateFlags::VERTEX_NON_FULL_WHITE;
uint8_t alpha = v0.color0 >> 24;
if (alpha != 0)
state->flags |= RasterizerStateFlags::VERTEX_ALPHA_NON_ZERO;
if (alpha != 0xFF)
state->flags |= RasterizerStateFlags::VERTEX_ALPHA_NON_FULL;
}
}
void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0) {
CalculateRasterStateFlags(state, v0, true);
}
void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0, const VertexData &v1, bool forceFlat) {
CalculateRasterStateFlags(state, v0, !forceFlat && state->shadeGouraud);
CalculateRasterStateFlags(state, v1, true);
}
void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0, const VertexData &v1, const VertexData &v2) {
CalculateRasterStateFlags(state, v0, state->shadeGouraud);
CalculateRasterStateFlags(state, v1, state->shadeGouraud);
CalculateRasterStateFlags(state, v2, true);
}
RasterizerState OptimizeFlatRasterizerState(const RasterizerState &origState, const VertexData &v1) {
uint8_t alpha = v1.color0 >> 24;
RasterizerState state = origState;

View File

@ -33,6 +33,16 @@ struct BinCoords;
namespace Rasterizer {
enum class RasterizerStateFlags {
NONE = 0,
VERTEX_NON_FULL_WHITE = 0x0001,
VERTEX_ALPHA_NON_ZERO = 0x0002,
VERTEX_ALPHA_NON_FULL = 0x0004,
INVALID = 0x7FFFFFFF,
};
ENUM_CLASS_BITOPS(RasterizerStateFlags);
struct RasterizerState {
PixelFuncID pixelID;
SamplerID samplerID;
@ -43,6 +53,7 @@ struct RasterizerState {
uint16_t texbufw[8]{};
const u8 *texptr[8]{};
float textureLodSlope;
RasterizerStateFlags flags = RasterizerStateFlags::NONE;
struct {
uint8_t maxTexLevel : 3;
@ -68,6 +79,9 @@ struct RasterizerState {
};
void ComputeRasterizerState(RasterizerState *state, std::function<void()> flushForCompile);
void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0);
void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0, const VertexData &v1, bool forceFlat);
void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0, const VertexData &v1, const VertexData &v2);
// Draws a triangle if its vertices are specified in counter-clockwise order
void DrawTriangle(const VertexData &v0, const VertexData &v1, const VertexData &v2, const BinCoords &range, const RasterizerState &state);