From 85dce2892183f9a5f31a2a00ae35a7e087fdf9a3 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 28 Aug 2023 14:07:02 -0400 Subject: [PATCH] shpuld's single-pass clipping optimization --- source/host.c | 69 ------ source/libpspmath/libpspmath.a | Bin 66154 -> 66154 bytes source/psp/video_hardware_model.h | 19 +- source/psp/video_hardware_surface.cpp | 313 ++++++++++---------------- 4 files changed, 131 insertions(+), 270 deletions(-) diff --git a/source/host.c b/source/host.c index 9cdcb1d..9408396 100644 --- a/source/host.c +++ b/source/host.c @@ -610,75 +610,6 @@ void Host_ServerFrame (void) SV_SendClientMessages (); } -int extshit() -{ - u32 size, sizeblock; - u8 *ram; - // Init variables - size = 0; - sizeblock = (1024 * 1024); - // Check loop - while (sizeblock) - { - // Increment size - size += sizeblock; - // Allocate ram - ram = (u8*)malloc(size); - // Check allocate - if (!(ram)) - { - // Restore old size - size -= sizeblock; - // Size block / 2 - sizeblock >>= 1; - } - else - free(ram); - } - - return size; -} - -int freememory() -{ - u8 **ram, **temp; - u32 size, count, x; - // Init variables - ram = NULL; - size = 0; - count = 0; - // Check loop - for (;;) - { - // Check size entries - if (!(count % 10)) - { - // Allocate more entries if needed - temp = (u8**)realloc(ram,sizeof(u8*) * (count + 10)); - if (!(temp)) break; - // Update entries and size (size contains also size of entries) - ram = temp; - size += (sizeof(u8 *) * 10); - } - // Find max lineare size available - x = extshit(); - if (!(x)) break; - // Allocate ram - ram[count] = (u8*)malloc(x); - if (!(ram[count])) break; - // Update variables - size += x; - count++; - } - // Free ram - if (ram) - { - for (x=0;xZ;XGXy0Ba?5Sif-OB1KG?8UP+t%<}sm~xw&Am1wv%=h82joG6%bYWgWs5=9531 zh}t}D^CP%D=9?RKl)&|abxgVmN*WA-^9Nr02mVI73X<_{-q5InF|KIcqWVM%lH zetXHy3objL2yD990oP)&dBQyzcnD*a9K4dBX}51P|;AmUYOk_;4a>^R&&65cX_t*inM2 zW717f+Th$Av(EuZ0-TNx>mWone>h=-;DN33Ifrifg3HKe00U*y%?^a7%@gj)z!R_K qWKhyO`y?D84~}BzS1Xa!fFhmy<4hzq6Yc>+`kMnumverts; - const glvert_t* const unclipped_vertices = &(p->verts[p->numverts]); - - if (clipping::is_clipping_required( - unclipped_vertices, - unclipped_vertex_count)) + if (r_showtris.value) { - // Clip the polygon. - const glvert_t* clipped_vertices; - std::size_t clipped_vertex_count; - clipping::clip( - unclipped_vertices, - unclipped_vertex_count, - &clipped_vertices, - &clipped_vertex_count); + sceGuDisable(GU_TEXTURE_2D); + sceGuDisable(GU_BLEND); - // Did we have any vertices left? - if (clipped_vertex_count) - { - // Copy the vertices to the display list. - const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); - glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); - memcpy(display_list_vertices, clipped_vertices, buffer_size); + // Draw the lines directly. + sceGumDrawArray( + GU_LINE_STRIP, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF , + poly->numclippedverts, 0, poly->display_list_verts); - // Draw the clipped vertices. - sceGuDrawArray( - GU_TRIANGLE_FAN, - GU_TEXTURE_32BITF | GU_VERTEX_32BITF , - clipped_vertex_count, 0, display_list_vertices); - } - } - else - { - // Draw the poly directly. - sceGuDrawArray( - GU_TRIANGLE_FAN, - GU_TEXTURE_32BITF | GU_VERTEX_32BITF , - unclipped_vertex_count, 0, unclipped_vertices); - } -} + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_BLEND); -static inline void DrawGLPoly (glpoly_t *p) -{ - // Does this poly need clipped? - const int unclipped_vertex_count = p->numverts; - const glvert_t* const unclipped_vertices = p->verts; - if (clipping::is_clipping_required( - unclipped_vertices, - unclipped_vertex_count)) - { - // Clip the polygon. - const glvert_t* clipped_vertices; - std::size_t clipped_vertex_count; - clipping::clip( - unclipped_vertices, - unclipped_vertex_count, - &clipped_vertices, - &clipped_vertex_count); - - // Did we have any vertices left? - if (clipped_vertex_count) - { - // Copy the vertices to the display list. - const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); - glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); - memcpy(display_list_vertices, clipped_vertices, buffer_size); - - // Draw the clipped vertices. - sceGuDrawArray( - GU_TRIANGLE_FAN, - GU_TEXTURE_32BITF | GU_VERTEX_32BITF, - clipped_vertex_count, 0, display_list_vertices); - } } else { // Draw the poly directly. sceGuDrawArray( GU_TRIANGLE_FAN, - GU_TEXTURE_32BITF | GU_VERTEX_32BITF, - unclipped_vertex_count, 0, unclipped_vertices); + GU_TEXTURE_32BITF | GU_VERTEX_32BITF , + poly->numclippedverts, 0, poly->display_list_verts); } } +static inline void DrawGLPoly (glpoly_t * poly) +{ + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + poly->numclippedverts, 0, poly->display_list_verts); +} + static inline void DrawTrisPoly (glpoly_t *p) //Crow_bar { sceGuDisable(GU_TEXTURE_2D); @@ -815,7 +769,6 @@ R_BlendLightmaps static void R_BlendLightmaps (void) { int i; - glpoly_t *p; if (r_fullbright.value) return; @@ -830,10 +783,11 @@ static void R_BlendLightmaps (void) if (r_lightmap.value) sceGuDisable(GU_BLEND); + lightmap_face_t * lmface; for (i=0 ; ichain) - { - if (p->flags & SURF_UNDERWATER) - { - DrawGLPolyLM(p); - //DrawGLWaterPolyLM(p); - } - else - DrawGLPolyLM(p); + for (; lmface; lmface = lmface->next) { + msurface_t * face = lmface->face; + float scale = 0.0625f; + float tscale = face->texinfo->texture->width / (BLOCK_WIDTH * 16.f); + float sscale = face->texinfo->texture->height / (BLOCK_HEIGHT * 16.f); + sceGuTexScale(tscale, sscale); + sceGuTexOffset( + tscale * (float)(-1.f * face->texturemins[0] + face->light_s * 16 + 8) / (float)(face->texinfo->texture->width), + sscale * (float)(-1.f * face->texturemins[1] + face->light_t * 16 + 8) / (float)(face->texinfo->texture->height) + ); + + DrawGLPolyLM(face->polys); } } if(LIGHTMAP_BYTES == 1) VID_SetPaletteTX(); + sceGuTexOffset(0, 0); + sceGuTexScale(1, 1); sceGuDisable(GU_BLEND); sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); sceGuDepthMask (GU_FALSE); sceGuEnable(GU_DEPTH_TEST); // dr_mabuse1981: fix } +int ClipFace (msurface_t * fa) +{ + // shpuld: moved clipping here to have it in one place only + int verts_total = 0; + glpoly_t* poly = fa->polys; + const int unclipped_vertex_count = poly->numverts; + const glvert_t* const unclipped_vertices = poly->verts; + + if (clipping::is_clipping_required( + unclipped_vertices, + unclipped_vertex_count)) + { + // Clip the polygon. + const glvert_t* clipped_vertices; + std::size_t clipped_vertex_count; + clipping::clip( + unclipped_vertices, + unclipped_vertex_count, + &clipped_vertices, + &clipped_vertex_count + ); + + verts_total += clipped_vertex_count; + + // Did we have any vertices left? + if (!clipped_vertex_count) + { + poly->numclippedverts = 0; + return verts_total; + } + + const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); + poly->display_list_verts = static_cast(sceGuGetMemory(buffer_size)); + memcpy(poly->display_list_verts, clipped_vertices, buffer_size); + poly->numclippedverts = clipped_vertex_count; + } else { + verts_total += unclipped_vertex_count; + + const std::size_t buffer_size = unclipped_vertex_count * sizeof(glvert_t); + poly->display_list_verts = static_cast(sceGuGetMemory(buffer_size)); + memcpy(poly->display_list_verts, unclipped_vertices, buffer_size); + poly->numclippedverts = unclipped_vertex_count; + } + return verts_total; +} + /* ================ R_RenderBrushPoly @@ -887,17 +892,12 @@ void R_RenderBrushPoly (msurface_t *fa) c_brush_polys++; - /*if(r_showtris.value) //Crow_bar - { - sceGuDepthMask (GU_TRUE); - - DrawTrisPoly (fa->polys); - - sceGuDepthMask (GU_FALSE); - }*/ - + // sky and water use multiple polys per surface, + // this makes clipping more tricky, but they don't have LMs so no prob. if (fa->flags & SURF_DRAWSKY) - { // warp texture, no lightmaps + { + // warp texture, no lightmaps + // shpuld: replace with scissor pass and then sky, maybe faster? EmitBothSkyLayers (fa); return; } @@ -911,6 +911,12 @@ void R_RenderBrushPoly (msurface_t *fa) return; } + // Everything from here only uses 1 poly from fa->polys + int verts_count = ClipFace(fa); + + if (verts_count <= 0) + return; + sceGuEnable(GU_ALPHA_TEST); sceGuAlphaFunc(GU_GREATER, 0xaa, 0xff); sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); @@ -931,10 +937,14 @@ void R_RenderBrushPoly (msurface_t *fa) } // motolegacy -- end texflags - // add the poly to the proper lightmap chain - fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; - lightmap_polys[fa->lightmaptexturenum] = fa->polys; - + // Manage lightmap chain + if (num_lightmapped_faces < MAX_VISIBLE_LIGHTMAPPED_FACES) + { + lightmap_faces[num_lightmapped_faces].face = fa; + lightmap_faces[num_lightmapped_faces].next = lightmap_chains[fa->lightmaptexturenum]; + lightmap_chains[fa->lightmaptexturenum] = &lightmap_faces[num_lightmapped_faces]; + num_lightmapped_faces++; + } // check for lightmap modification for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; maps++) @@ -976,64 +986,6 @@ dynamic: sceGuDisable(GU_ALPHA_TEST); } -/* -================ -R_RenderDynamicLightmaps -Multitexture -================ -*/ -void R_RenderDynamicLightmaps (msurface_t *fa) -{ - byte *base; - int maps; - glRect_t *theRect; - int smax, tmax; - - c_brush_polys++; - - if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) ) - return; - - fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; - lightmap_polys[fa->lightmaptexturenum] = fa->polys; - - // check for lightmap modification - for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; - maps++) - if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) - goto dynamic; - - if (fa->dlightframe == r_framecount // dynamic this frame - || fa->cached_dlight) // dynamic previously - { -dynamic: - if (r_dynamic.value) - { - lightmap_modified[fa->lightmaptexturenum] = qtrue; - theRect = &lightmap_rectchange[fa->lightmaptexturenum]; - if (fa->light_t < theRect->t) { - if (theRect->h) - theRect->h += theRect->t - fa->light_t; - theRect->t = fa->light_t; - } - if (fa->light_s < theRect->l) { - if (theRect->w) - theRect->w += theRect->l - fa->light_s; - theRect->l = fa->light_s; - } - smax = (fa->extents[0]>>4)+1; - tmax = (fa->extents[1]>>4)+1; - if ((theRect->w + theRect->l) < (fa->light_s + smax)) - theRect->w = (fa->light_s-theRect->l)+smax; - if ((theRect->h + theRect->t) < (fa->light_t + tmax)) - theRect->h = (fa->light_t-theRect->t)+tmax; - base = lightmaps + fa->lightmaptexturenum*LIGHTMAP_BYTES*BLOCK_WIDTH*BLOCK_HEIGHT; - base += fa->light_t * BLOCK_WIDTH * LIGHTMAP_BYTES + fa->light_s * LIGHTMAP_BYTES; - R_BuildLightMap (fa, base, BLOCK_WIDTH*LIGHTMAP_BYTES); - } - } -} - /* ================ R_MirrorChain @@ -1227,7 +1179,8 @@ void R_DrawBrushModel (entity_t *e) } - memset (lightmap_polys, 0, sizeof(lightmap_polys)); + memset (lightmap_chains, 0, sizeof(lightmap_chains)); + num_lightmapped_faces = 0; VectorSubtract (r_refdef.vieworg, e->origin, modelorg); if (rotated) @@ -1526,7 +1479,8 @@ void R_DrawWorld (void) currenttexture = -1; /*glColor3f (1,1,1);*/ - memset (lightmap_polys, 0, sizeof(lightmap_polys)); + memset (lightmap_chains, 0, sizeof(lightmap_chains)); + num_lightmapped_faces = 0; R_ClearSkyBox (); @@ -1673,7 +1627,7 @@ static void BuildSurfaceDisplayList (msurface_t *fa) // // draw texture // - poly = static_cast(Hunk_Alloc (sizeof(glpoly_t) + (lnumverts * 2 - 1) * sizeof(glvert_t))); + poly = static_cast(Hunk_Alloc (sizeof(glpoly_t) + (lnumverts - 1) * sizeof(glvert_t))); poly->next = fa->polys; poly->flags = fa->flags; fa->polys = poly; @@ -1702,25 +1656,6 @@ static void BuildSurfaceDisplayList (msurface_t *fa) VectorCopy(vec, poly->verts[i].xyz); poly->verts[i].st[0] = s; poly->verts[i].st[1] = t; - - // - // lightmap texture coordinates - // - s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; - s -= fa->texturemins[0]; - s += fa->light_s*16; - s += 8; - s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width; - - t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; - t -= fa->texturemins[1]; - t += fa->light_t*16; - t += 8; - t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height; - - VectorCopy(vec, poly->verts[i + lnumverts].xyz); - poly->verts[i + lnumverts].st[0] = s; - poly->verts[i + lnumverts].st[1] = t; } // @@ -1760,7 +1695,6 @@ static void BuildSurfaceDisplayList (msurface_t *fa) for (j = i + 1; j < lnumverts; j = j + 1) { poly->verts[j - 1] = poly->verts[j]; - poly->verts[poly->numverts + j - 1] = poly->verts[poly->numverts+j]; } --lnumverts; @@ -1770,12 +1704,6 @@ static void BuildSurfaceDisplayList (msurface_t *fa) --i; } } - - if (numRemoved > 0) { - for (j = poly->numverts; j < poly->numverts + lnumverts; j++) { - poly->verts[j - numRemoved] = poly->verts[j]; - } - } } // Colinear point removal-end @@ -1846,6 +1774,7 @@ void GL_BuildLightmaps (void) currentmodel = m; for (i=0 ; inumsurfaces ; i++) { + // todo: investigate why this is done even for turb/sky GL_CreateSurfaceLightmap (m->surfaces + i); if ( m->surfaces[i].flags & SURF_DRAWTURB ) continue;