Skip to content

Commit

Permalink
softgpu: Move texture addresses to prim state.
Browse files Browse the repository at this point in the history
  • Loading branch information
unknownbrackets committed Jan 11, 2022
1 parent d5c5e94 commit 75ff3e4
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 57 deletions.
74 changes: 27 additions & 47 deletions GPU/Software/Rasterizer.cpp
Expand Up @@ -102,6 +102,27 @@ static inline Vec4<float> Interpolate(const float &c0, const float &c1, const fl
return Interpolate(c0, c1, c2, w0.Cast<float>(), w1.Cast<float>(), w2.Cast<float>(), wsum_recip);
}

void ComputeRasterizerState(RasterizerState *state) {
ComputePixelFuncID(&state->pixelID);
ComputeSamplerID(&state->samplerID);
state->drawPixel = Rasterizer::GetSingleFunc(state->pixelID);
state->linear = Sampler::GetLinearFunc(state->samplerID);
state->nearest = Sampler::GetNearestFunc(state->samplerID);

int maxTexLevel = state->samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0;
if (gstate.isTextureMapEnabled() && !state->pixelID.clearMode) {
GETextureFormat texfmt = state->samplerID.TexFmt();
for (int i = 0; i <= maxTexLevel; i++) {
u32 texaddr = gstate.getTextureAddress(i);
state->texbufw[i] = GetTextureBufw(i, texaddr, texfmt);
if (Memory::IsValidAddress(texaddr))
state->texptr[i] = Memory::GetPointerUnchecked(texaddr);
else
state->texptr[i] = nullptr;
}
}
}

static inline u8 ClampFogDepth(float fogdepth) {
union FloatBits {
float f;
Expand Down Expand Up @@ -478,7 +499,7 @@ Vec3<int> AlphaBlendingResult(const PixelFuncID &pixelID, const Vec4<int> &sourc
}
}

static inline Vec4IntResult SOFTRAST_CALL ApplyTexturing(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *texptr[], int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) {
static inline Vec4IntResult SOFTRAST_CALL ApplyTexturing(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *const texptr[], const int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) {
const u8 **tptr0 = const_cast<const u8 **>(&texptr[texlevel]);
const int *bufw0 = &texbufw[texlevel];

Expand All @@ -488,7 +509,7 @@ static inline Vec4IntResult SOFTRAST_CALL ApplyTexturing(float s, float t, int x
return state.linear(s, t, x, y, prim_color, tptr0, bufw0, texlevel, frac_texlevel);
}

static inline Vec4IntResult SOFTRAST_CALL ApplyTexturingSingle(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *texptr[], int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) {
static inline Vec4IntResult SOFTRAST_CALL ApplyTexturingSingle(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *const texptr[], const int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) {
return ApplyTexturing(s, t, ((x & 15) + 1) / 2, ((y & 15) + 1) / 2, prim_color, texptr, texbufw, texlevel, frac_texlevel, bilinear, state);
}

Expand Down Expand Up @@ -555,7 +576,7 @@ static inline void CalculateSamplingParams(const float ds, const float dt, const
}
}

static inline void ApplyTexturing(const RasterizerState &state, Vec4<int> *prim_color, const Vec4<int> &mask, const Vec4<float> &s, const Vec4<float> &t, int maxTexLevel, u8 *texptr[], int texbufw[], int x, int y) {
static inline void ApplyTexturing(const RasterizerState &state, Vec4<int> *prim_color, const Vec4<int> &mask, const Vec4<float> &s, const Vec4<float> &t, int maxTexLevel, u8 *const texptr[], const int texbufw[], int x, int y) {
float ds = s[1] - s[0];
float dt = t[2] - t[0];

Expand Down Expand Up @@ -750,23 +771,7 @@ void DrawTriangleSlice(
Vec4<int> bias2 = Vec4<int>::AssignToAll(IsRightSideOrFlatBottomLine(v2.screenpos.xy(), v0.screenpos.xy(), v1.screenpos.xy()) ? -1 : 0);

const PixelFuncID &pixelID = state.pixelID;

int texbufw[8]{};

int maxTexLevel = state.samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0;
u8 *texptr[8]{};

if (gstate.isTextureMapEnabled() && !clearMode) {
GETextureFormat texfmt = state.samplerID.TexFmt();
for (int i = 0; i <= maxTexLevel; i++) {
u32 texaddr = gstate.getTextureAddress(i);
texbufw[i] = GetTextureBufw(i, texaddr, texfmt);
if (Memory::IsValidAddress(texaddr))
texptr[i] = Memory::GetPointerUnchecked(texaddr);
else
texptr[i] = 0;
}
}

TriangleEdge<useSSE4> e0;
TriangleEdge<useSSE4> e1;
Expand Down Expand Up @@ -872,7 +877,7 @@ void DrawTriangleSlice(
GetTextureCoordinates(v0, v1, v2, w0, w1, w2, wsum_recip, s, t);
}

ApplyTexturing(state, prim_color, mask, s, t, maxTexLevel, texptr, texbufw, curX, curY);
ApplyTexturing(state, prim_color, mask, s, t, maxTexLevel, state.texptr, state.texbufw, curX, curY);
}

if (!clearMode) {
Expand Down Expand Up @@ -1029,20 +1034,7 @@ void DrawPoint(const VertexData &v0, const RasterizerState &state) {
auto &samplerID = state.samplerID;

if (gstate.isTextureMapEnabled() && !pixelID.clearMode) {
int texbufw[8] = {0};

int maxTexLevel = samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0;
u8 *texptr[8] = {NULL};

GETextureFormat texfmt = samplerID.TexFmt();
for (int i = 0; i <= maxTexLevel; i++) {
u32 texaddr = gstate.getTextureAddress(i);
texbufw[i] = GetTextureBufw(i, texaddr, texfmt);
if (Memory::IsValidAddress(texaddr))
texptr[i] = Memory::GetPointerUnchecked(texaddr);
else
texptr[i] = 0;
}

float s = v0.texturecoords.s();
float t = v0.texturecoords.t();
Expand All @@ -1059,7 +1051,7 @@ void DrawPoint(const VertexData &v0, const RasterizerState &state) {
bool bilinear;
CalculateSamplingParams(0.0f, 0.0f, maxTexLevel, texLevel, texLevelFrac, bilinear);
PROFILE_THIS_SCOPE("sampler");
prim_color = ApplyTexturingSingle(s, t, pos.x, pos.y, ToVec4IntArg(prim_color), texptr, texbufw, texLevel, texLevelFrac, bilinear, state);
prim_color = ApplyTexturingSingle(s, t, pos.x, pos.y, ToVec4IntArg(prim_color), state.texptr, state.texbufw, texLevel, texLevelFrac, bilinear, state);
}

if (!pixelID.clearMode)
Expand Down Expand Up @@ -1312,19 +1304,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const RasterizerState
scissorBR.x += 15;
scissorBR.y += 15;

int texbufw[8] = {0};

int maxTexLevel = state.samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0;
u8 *texptr[8] = {NULL};

if (gstate.isTextureMapEnabled() && !state.pixelID.clearMode) {
GETextureFormat texfmt = state.samplerID.TexFmt();
for (int i = 0; i <= maxTexLevel; i++) {
u32 texaddr = gstate.getTextureAddress(i);
texbufw[i] = GetTextureBufw(i, texaddr, texfmt);
texptr[i] = Memory::GetPointer(texaddr);
}
}

auto &pixelID = state.pixelID;
auto &samplerID = state.samplerID;
Expand Down Expand Up @@ -1401,7 +1381,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const RasterizerState
}

PROFILE_THIS_SCOPE("sampler");
prim_color = ApplyTexturingSingle(s, t, x, y, ToVec4IntArg(prim_color), texptr, texbufw, texLevel, texLevelFrac, texBilinear, state);
prim_color = ApplyTexturingSingle(s, t, x, y, ToVec4IntArg(prim_color), state.texptr, state.texbufw, texLevel, texLevelFrac, texBilinear, state);
}

if (!pixelID.clearMode)
Expand Down
4 changes: 4 additions & 0 deletions GPU/Software/Rasterizer.h
Expand Up @@ -38,8 +38,12 @@ struct RasterizerState {
SingleFunc drawPixel;
Sampler::LinearFunc linear;
Sampler::NearestFunc nearest;
int texbufw[8]{};
u8 *texptr[8]{};
};

void ComputeRasterizerState(RasterizerState *state);

// Draws a triangle if its vertices are specified in counter-clockwise order
void DrawTriangle(const VertexData &v0, const VertexData &v1, const VertexData &v2, const RasterizerState &state);
void DrawPoint(const VertexData &v0, const RasterizerState &state);
Expand Down
7 changes: 2 additions & 5 deletions GPU/Software/RasterizerRectangle.cpp
Expand Up @@ -78,13 +78,10 @@ static inline Vec4IntResult SOFTRAST_CALL ModulateRGBA(Vec4IntArg prim_in, Vec4I
}

void DrawSprite(const VertexData &v0, const VertexData &v1, const RasterizerState &state) {
const u8 *texptr = nullptr;
const u8 *texptr = state.texptr[0];

GETextureFormat texfmt = state.samplerID.TexFmt();
u32 texaddr = gstate.getTextureAddress(0);
int texbufw = GetTextureBufw(0, texaddr, texfmt);
if (Memory::IsValidAddress(texaddr))
texptr = Memory::GetPointerUnchecked(texaddr);
int texbufw = state.texbufw[0];

ScreenCoords pprime(v0.screenpos.x, v0.screenpos.y, 0);
Sampler::FetchFunc fetchFunc = Sampler::GetFetchFunc(state.samplerID);
Expand Down
7 changes: 2 additions & 5 deletions GPU/Software/TransformUnit.cpp
Expand Up @@ -27,6 +27,7 @@
#include "GPU/Common/DrawEngineCommon.h"
#include "GPU/Common/VertexDecoderCommon.h"
#include "GPU/Common/SplineCommon.h"
#include "GPU/Common/TextureDecoder.h"
#include "GPU/Debugger/Debugger.h"
#include "GPU/Software/Clipper.h"
#include "GPU/Software/FuncId.h"
Expand Down Expand Up @@ -342,11 +343,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
// then resolve the indices. This lets us avoid transforming shared vertices twice.

Rasterizer::RasterizerState state;
ComputePixelFuncID(&state.pixelID);
ComputeSamplerID(&state.samplerID);
state.drawPixel = Rasterizer::GetSingleFunc(state.pixelID);
state.linear = Sampler::GetLinearFunc(state.samplerID);
state.nearest = Sampler::GetNearestFunc(state.samplerID);
ComputeRasterizerState(&state);

bool outside_range_flag = false;
switch (prim_type) {
Expand Down

0 comments on commit 75ff3e4

Please sign in to comment.