Browse Source

Made polygon building faster by checking ahead of time if we have enough primitive buffer space, instead of checking it per polygon.

Also the primitive buffer management is now all done through inline functions.
tess_experiment
Nico de Poel 3 years ago
parent
commit
e1d239150e
  1. 32
      memory.c
  2. 33
      memory.h
  3. 18
      world.c

32
memory.c

@ -1,38 +1,14 @@
#include "common.h"
#include "memory.h"
#define PRIMBUFLEN 131072 // TODO: optimize this for a typical scene
static char primbuff[2][PRIMBUFLEN]; // Primitive buffer, just a raw buffer of bytes to use as a pool for primitives
static char *nextpri;
static char *primbuff_bounds;
char *nextprim;
char *primbuf_bounds;
u_char* const scratchpad = (char*)0x1F800000;
void *mem_scratch(char **scratch_offset, unsigned short size)
{
#if _DEBUG
if (*scratch_offset + size > scratchpad + 1024)
return NULL;
#endif
void *result = *scratch_offset;
*scratch_offset += size;
return result;
}
void mem_prim_reset(int db)
{
nextpri = primbuff[db];
primbuff_bounds = nextpri + PRIMBUFLEN;
}
void *mem_prim(size_t size)
{
if (nextpri + size > primbuff_bounds)
return NULL; // TODO: report error
void *prim = nextpri;
nextpri += size;
return prim;
nextprim = primbuff[db];
primbuf_bounds = nextprim + PRIMBUFLEN;
}

33
memory.h

@ -1,16 +1,12 @@
#ifndef __MEMORY_H__
#define __MEMORY_H__
extern u_char* const scratchpad; // Starting address of scratchpad memory
#define SCRATCHLEN 1024
extern u_char* const scratchpad; // Starting address of scratchpad memory, i.e. the 1kB of data cache usable as fast RAM
/**
* @brief Allocate memory in the fast scratchpad RAM buffer.
*
* @param scratch_offset Pointer to a variable holding the current offset position in scratch memory.
* @param size The number of bytes to allocate. Be aware that the scratchpad memory only has 1024 bytes available.
* @return Pointer to the allocated buffer in scratchpad memory.
*/
void *mem_scratch(char **scratch_offset, unsigned short size);
#define PRIMBUFLEN 65536 // TODO: reduce this to what's needed for a typical scene
extern char *nextprim;
extern char *primbuf_bounds;
/**
* @brief Allocate a single primitive in the primitive buffer.
@ -18,7 +14,24 @@ void *mem_scratch(char **scratch_offset, unsigned short size);
* @param size Size of the primitive struct to allocate.
* @return Pointer to the allocated struct in memory.
*/
void *mem_prim(size_t size);
INLINE void *mem_prim(size_t size)
{
void *prim = nextprim;
nextprim += size;
return prim;
}
/**
* @brief Check if it's safe to allocate the given number of primitives of the given size.
*
* @param size The size of each primitive to allocate.
* @param count The number of primitives to allocate.
* @return Whether the number of primitives can be allocated without exceeding the primitive buffer bounds.
*/
INLINE char mem_checkprim(size_t size, u_short count)
{
return nextprim + size * count < primbuf_bounds;
}
void mem_prim_reset(int db);

18
world.c

@ -53,6 +53,9 @@ static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vec
{
int p;
if (!mem_checkprim(sizeof(POLY_G3), face->numFaceVertices))
return;
// Draw the face as a triangle fan
u_char maxVert = face->numFaceVertices - 1;
for (int vertIdx = 1; vertIdx < maxVert; ++vertIdx)
@ -74,9 +77,6 @@ static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vec
// Draw a flat-shaded untextured colored triangle
POLY_G3 *poly = (POLY_G3*)mem_prim(sizeof(POLY_G3));
if (poly == NULL)
break;
setPolyG3(poly);
gte_stsxy3_g3(poly);
@ -93,6 +93,9 @@ static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *v
{
int p;
if (!mem_checkprim(sizeof(POLY_G3), face->numFaceVertices))
return;
// Draw the face as a triangle strip
const SVECTOR *v0, *v1, *v2;
const SVECTOR *head = vecs;
@ -130,9 +133,6 @@ static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *v
// Draw a flat-shaded untextured colored triangle
POLY_G3 *poly = (POLY_G3*)mem_prim(sizeof(POLY_G3));
if (poly == NULL)
break;
setPolyG3(poly);
gte_stsxy3_g3(poly);
@ -149,6 +149,9 @@ static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs)
{
int p;
if (!mem_checkprim(sizeof(POLY_G4), face->numFaceVertices))
return;
// Draw the face as a quad strip
const SVECTOR *v0, *v1, *v2, *v3;
const SVECTOR *head = vecs;
@ -180,9 +183,6 @@ static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs)
// Draw a flat-shaded untextured colored quad
POLY_G4 *poly = (POLY_G4*)mem_prim(sizeof(POLY_G4));
if (poly == NULL)
break;
setPolyG4(poly);
gte_stsxy0(&poly->x0);
gte_stsxy1(&poly->x1);

Loading…
Cancel
Save