SoftGPU: Optimise for when fallback textures are used

This commit is contained in:
UnknownShadow200 2025-07-02 20:54:56 +10:00
parent b1905750be
commit 9b55b3a958
6 changed files with 21 additions and 12 deletions

View File

@ -481,7 +481,7 @@ static void Game_Load(void) {
if (Gfx.Limitations & GFX_LIMIT_VERTEX_ONLY_FOG)
EnvRenderer_SetMode(EnvRenderer_Minimal | ENV_LEGACY);
if (Gfx.Limitations & GFX_LIMIT_NO_FOG)
if (Gfx.Limitations & GFX_LIMIT_MINIMAL)
EnvRenderer_SetMode(ENV_MINIMAL);
Server.BeginConnect();

View File

@ -93,8 +93,8 @@ CC_VAR extern struct _GfxData {
#define GFX_LIMIT_VERTEX_ONLY_FOG 0x02
/* Whether the graphics backend only supports a small maximum quad size */
#define GFX_LIMIT_MAX_VERTEX_SIZE 0x04
/* Whether the graphics backend doesn't support fog at all */
#define GFX_LIMIT_NO_FOG 0x08
/* Whether the graphics backend is minimal (no fog, clouds, sky) */
#define GFX_LIMIT_MINIMAL 0x08
extern const cc_string Gfx_LowPerfMessage;

View File

@ -130,8 +130,7 @@ void Gfx_Create(void) {
Gfx.MaxTexHeight = 256;
//Gfx.MaxTexSize = 256 * 256;
Gfx.Created = true;
//Gfx.Limitations = GFX_LIMIT_VERTEX_ONLY_FOG;
Gfx.Limitations = GFX_LIMIT_NO_FOG;
Gfx.Limitations = GFX_LIMIT_VERTEX_ONLY_FOG;
ResetGPU();
Gfx_ClearColor(PackedCol_Make(0, 120, 80, 255));

View File

@ -117,7 +117,7 @@ void Gfx_Create(void) {
Gfx.MaxTexWidth = 128;
Gfx.MaxTexHeight = 16; // 128
Gfx.Created = true;
Gfx.Limitations = GFX_LIMIT_NO_UV_SUPPORT | GFX_LIMIT_MAX_VERTEX_SIZE | GFX_LIMIT_NO_FOG;
Gfx.Limitations = GFX_LIMIT_NO_UV_SUPPORT | GFX_LIMIT_MAX_VERTEX_SIZE;
SetupHeaderCommands();
}

View File

@ -49,7 +49,7 @@ void Gfx_Create(void) {
Gfx.Created = true;
Gfx.BackendType = CC_GFX_BACKEND_SOFTGPU;
Gfx.Limitations = GFX_LIMIT_NO_FOG;
Gfx.Limitations = GFX_LIMIT_MINIMAL;
Gfx_RestoreState();
}
@ -88,7 +88,11 @@ void Gfx_BindTexture(GfxResourceID texId) {
texWidthMask = (1 << Math_ilog2(tex->width)) - 1;
texHeightMask = (1 << Math_ilog2(tex->height)) - 1;
texSinglePixel = curTexWidth == 1 && curTexHeight == 1;
/* Technically the optimisation should only apply if width and height is 1 */
/* But it's worth sacrificing this, so that rendering the world when */
/* no texture pack can use the more optimised rendering path */
texSinglePixel = curTexWidth == 1;
}
void Gfx_DeleteTexture(GfxResourceID* texId) {
@ -469,7 +473,6 @@ static void DrawTriangle2D(Vertex* V0, Vertex* V1, Vertex* V2) {
int maxX = max(x0, max(x1, x2));
int maxY = max(y0, max(y1, y2));
int area = edgeFunction(x0,y0, x1,y1, x2,y2);
// Reject triangles completely outside
if (maxX < 0 || minX > fb_maxX) return;
if (maxY < 0 || minY > fb_maxY) return;
@ -477,11 +480,13 @@ static void DrawTriangle2D(Vertex* V0, Vertex* V1, Vertex* V2) {
// Perform scissoring
minX = max(minX, 0); maxX = min(maxX, fb_maxX);
minY = max(minY, 0); maxY = min(maxY, fb_maxY);
float factor = 1.0f / area;
float u0 = V0->u * curTexWidth, u1 = V1->u * curTexWidth, u2 = V2->u * curTexWidth;
float v0 = V0->v * curTexHeight, v1 = V1->v * curTexHeight, v2 = V2->v * curTexHeight;
PackedCol color = V0->c;
int area = edgeFunction(x0,y0, x1,y1, x2,y2);
float factor = 1.0f / area;
// https://fgiesen.wordpress.com/2013/02/10/optimizing-the-basic-rasterizer/
// Essentially these are the deltas of edge functions between X/Y and X/Y + 1 (i.e. one X/Y step)
@ -628,7 +633,12 @@ static void DrawTriangle3D(Vertex* V0, Vertex* V1, Vertex* V2) {
A = PackedCol_A(color);
} else if (texSinglePixel) {
/* Don't need to calculate complicated texturing in this case */
MultiplyColors(color, curTexPixels[0]);
float rawY0 = v0 / w0;
float rawY1 = v1 / w1;
float rawY = min(rawY0, rawY1);
int texY = (int)(rawY + 0.01f) & texHeightMask;
MultiplyColors(color, curTexPixels[texY * curTexWidth]);
texturing = false;
}

View File

@ -173,7 +173,7 @@ void Gfx_Create(void) {
Gfx.MaxTexWidth = 256;
Gfx.MaxTexHeight = 256;
Gfx.Created = true;
Gfx.Limitations = GFX_LIMIT_MAX_VERTEX_SIZE | GFX_LIMIT_NO_FOG;
Gfx.Limitations = GFX_LIMIT_MAX_VERTEX_SIZE;
Gfx_RestoreState();
SetupContexts(Window_Main.Width, Window_Main.Height);