Load flats into IPU texture blob. Batch up span requests on render tiles, ready to exchange them with the texture tiles.

This commit is contained in:
jndean
2023-11-25 22:24:21 +00:00
parent 7a7179fcb9
commit 162df95ec8
11 changed files with 122 additions and 41 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ Activity Log:
- [x] Split rendering across 32 render tiles. Reformat textures into a big buffer that can be striped over dedicated texture tiles, and accessed by the render tiles using JIT-patched exchange programs to enable fetches based on dynamic indices. So now IPU can texture walls.
![Gameplay with textured walls (but nothing else)](README_imgs/WallsTextured_noCPU.gif)![Gameplay showing rendering striped across 32 tiles](README_imgs/WallsTileGrey_noCPU.gif )
![Gameplay with textured walls (but nothing else)](README_imgs/WallsTextured_noCPU.gif) ![Gameplay showing rendering striped across 32 tiles](README_imgs/WallsTileGrey_noCPU.gif )
- [x] Implement lighting model (add shadows to walls): texture tiles translate the colours during texture column fetch requests to save memory on the render tiles.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

+15 -11
View File
@@ -2,20 +2,21 @@
#include <poplar/TileConstants.hpp>
#include <poplar/Vertex.hpp>
#include "doomtype.h"
#include "r_data.h"
#include "r_main.h"
#include "r_segs.h"
extern "C" {
#include "doomtype.h"
#include "r_data.h"
#include "r_draw.h"
#include "r_main.h"
#include "r_segs.h"
#include "ipu_interface.h"
#include "ipu_utils.h"
#include "ipu_texturetiles.h"
}
#include "ipu_interface.h"
#include "ipu_utils.h"
#include "ipu_texturetiles.h"
#include "../../xcom.hpp"
#define IS_SPAN (0x800000)
// Remeber! Copies of these vars exits independently on each tile
unsigned* tileLocalProgBuf;
unsigned* tileLocalCommsBuf;
@@ -146,7 +147,6 @@ static int muxInstructionOffset;
extern "C"
__SUPER__
void IPU_R_InitColumnRequester(unsigned* progBuf, int progBufSize) {
// Figure out which tiles to talk to
int firstTextureTile = IPUFIRSTTEXTURETILE + (IPUTEXTURETILESPERRENDERTILE * (tileID - IPUFIRSTRENDERTILE));
for (int i = 0; i < IPUTEXTURETILESPERRENDERTILE; ++i) {
@@ -304,6 +304,10 @@ byte* IPU_R_RequestColumn(int texture, int column) {
extern "C"
__SUPER__
void IPU_R_RenderTileDone() {
// First flush the last possibly incomplete spanRequest batch
IPURequest_R_DrawSpan_FulfillBatch();
// progBuff starts with a program directory
auto requestProg = &tileLocalProgBuf[tileLocalProgBuf[0]];
auto aggregateProg = &tileLocalProgBuf[tileLocalProgBuf[2]];
+18 -8
View File
@@ -8,26 +8,36 @@ extern "C" {
#include "doomtype.h"
#include "ipu_interface.h"
#include "ipu_utils.h"
struct IPUColRequest_t {
#define IPUTEXREQUESTISSPAN (0x800000)
#define IPUMAXSPANREQUESTBATCHSIZE (5)
typedef struct {
unsigned columnOffset, lightNum, lightScale;
};
struct IPUSpanRequest_t {
} IPUColRequest_t;
typedef struct {
unsigned position, step;
short ds_x1, ds_x2;
unsigned char y, light;
};
unsigned char count, lightNum;
} IPUSpanRequest_t;
typedef struct {
unsigned texture;
union {
struct IPUColRequest_t colRequest;
struct IPUSpanRequest_t spanRequest;
IPUColRequest_t colRequest;
IPUSpanRequest_t spanRequests[IPUMAXSPANREQUESTBATCHSIZE];
};
unsigned short numSpanRequests;
} IPUTextureRequest_t;
#ifdef __cplusplus
static_assert((IPUTEXTURECACHELINESIZE * sizeof(int)) >= sizeof(IPUTextureRequest_t),
"Texture cache buf is used to store the request at one point");
#endif
extern unsigned* tileLocalProgBuf;
extern unsigned* tileLocalCommsBuf;
+63
View File
@@ -41,6 +41,7 @@
#include <print.h>
#include "ipu_interface.h"
#include "ipu_texturetiles.h"
// ?
#define MAXWIDTH 1120
@@ -576,6 +577,68 @@ void R_DrawSpan(void) {
}
//
// On the IPU, each render tile accrues a batch of R_DrawSpan requests
// then exchanges them with texture tiles for fulfilment
//
static IPUTextureRequest_t requestBatch;
static pixel_t* spanDests[IPUMAXSPANREQUESTBATCHSIZE];
__SUPER__
void IPURequest_R_DrawSpan_FulfillBatch(void) {
IPUTextureRequest_t* requestBuf = (IPUTextureRequest_t*) tileLocalTextureBuf;
memcpy(requestBuf, &requestBatch, sizeof(requestBatch));
requestBuf->texture |= IPUTEXREQUESTISSPAN;
// TMP: Fill the span with fixed colour
for (int i = 0; i < requestBatch.numSpanRequests; ++i) {
IPUSpanRequest_t* spanRequest = &requestBatch.spanRequests[i];
pixel_t* dest = spanDests[i];
for (int i = 0; i <= spanRequest->count; i++) {
*dest++ = 20;
}
}
requestBatch.numSpanRequests = 0;
}
// The render-tile side of the span requesting system
__SUPER__
void IPURequest_R_DrawSpan(void) {
unsigned int position, step;
pixel_t *dest;
int count;
if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= SCREENWIDTH ||
(unsigned)ds_y > SCREENHEIGHT) {
printf("ERROR: R_DrawSpan: %d to %d at %d\n", ds_x1, ds_x2, ds_y);
return;
}
if (requestBatch.numSpanRequests > 0 && requestBatch.texture != flatnum) {
IPURequest_R_DrawSpan_FulfillBatch();
}
requestBatch.texture = flatnum;
IPUSpanRequest_t* spanRequest = &requestBatch.spanRequests[requestBatch.numSpanRequests];
spanRequest->position = ((ds_xfrac << 10) & 0xffff0000) | ((ds_yfrac >> 6) & 0x0000ffff);
spanRequest->step = ((ds_xstep << 10) & 0xffff0000) | ((ds_ystep >> 6) & 0x0000ffff);
spanRequest->count = ds_x2 - ds_x1;
spanRequest->lightNum = lightnum;
spanDests[requestBatch.numSpanRequests] = ylookup[ds_y] + columnofs[ds_x1];
requestBatch.numSpanRequests += 1;
if (requestBatch.numSpanRequests >= IPUMAXSPANREQUESTBATCHSIZE) {
IPURequest_R_DrawSpan_FulfillBatch();
}
}
/*
// UNUSED.
// Loop unrolled by 4.
+2
View File
@@ -71,6 +71,8 @@ extern byte *dc_translation;
// Span blitting for rows, floor/ceiling.
// No Sepctre effect needed.
void R_DrawSpan(void);
__SUPER__ void IPURequest_R_DrawSpan(void);
__SUPER__ void IPURequest_R_DrawSpan_FulfillBatch(void);
// Low resolution mode, 160x200?
void R_DrawSpanLow(void);
+4
View File
@@ -96,6 +96,10 @@ extern void (*spanfunc)(void);
// JOSEF
extern int tileLeftClip;
extern int tileRightClip;
extern int lightnum;
extern unsigned walllightindex;
extern int flatnum;
//
// Utility functions.
+19 -14
View File
@@ -97,6 +97,9 @@ fixed_t cacheddistance[SCREENHEIGHT];
fixed_t cachedxstep[SCREENHEIGHT];
fixed_t cachedystep[SCREENHEIGHT];
// JOSEF: Global to pass over exchange
int flatnum;
__SUPER__
int abs(int x); // JOSEF
@@ -170,6 +173,7 @@ void R_MapPlane(int y, int x1, int x2) {
// high or low detail
// spanfunc(); // LATER
// R_DrawSpan();
IPURequest_R_DrawSpan();
}
//
@@ -325,7 +329,7 @@ void R_MakeSpans(int x, int t1, int b1, int t2, int b2) {
__SUPER__
void R_DrawPlanes(void) {
visplane_t *pl;
int light;
// int light; JOSEF: store in `lightnum` instead herein
int x;
int stop;
int angle;
@@ -374,21 +378,22 @@ void R_DrawPlanes(void) {
continue;
}
// LATER
// JOSEF: Don't load lump, just record flatnum to send over exchange later
flatnum = pl->picnum; // LATER: flattranslation[pl->picnum];
// regular flat
// lumpnum = firstflat + flattranslation[pl->picnum];
// ds_source = W_CacheLumpNum(lumpnum, PU_STATIC);
planeheight = abs(pl->height - viewz);
light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight;
lightnum = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight;
if (light >= LIGHTLEVELS)
light = LIGHTLEVELS - 1;
if (lightnum >= LIGHTLEVELS)
lightnum = LIGHTLEVELS - 1;
if (light < 0)
light = 0;
if (lightnum < 0)
lightnum = 0;
// // planezlight = zlight[light]; // LATER
// // planezlight = zlight[light]; // Texture tiles are in charge of scaling by light
pl->top[pl->maxx + 1] = 0xff;
pl->top[pl->minx - 1] = 0xff;
@@ -400,15 +405,15 @@ void R_DrawPlanes(void) {
pl->bottom[x]);
// JOSEF: TMP solid colour visualisation
pixel_t colour = (140 + (pl - visplanes) * 2) % 256;
// pixel_t colour = (140 + (pl - visplanes) * 2) % 256;
// pixel_t colour = (pl->picnum * 17 + 209) % 256;
for (int y = pl->top[x]; y <= pl->bottom[x]; y++) {
pixel_t* dest = (I_VideoBuffer + (y + viewwindowy) * IPUCOLSPERRENDERTILE) + (viewwindowx + x - tileLeftClip);
*dest = colour;
}
// for (int y = pl->top[x]; y <= pl->bottom[x]; y++) {
// pixel_t* dest = (I_VideoBuffer + (y + viewwindowy) * IPUCOLSPERRENDERTILE) + (viewwindowx + x - tileLeftClip);
// *dest = colour;
// }
}
// W_ReleaseLumpNum(lumpnum); // LATER
// W_ReleaseLumpNum(lumpnum); // JOSEF
}
}
-3
View File
@@ -22,9 +22,6 @@
#include "ipu_texturetiles.h"
#include "r_defs.h"
extern int lightnum;
extern unsigned walllightindex;
__SUPER__ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2);
#endif
-1
View File
@@ -837,7 +837,6 @@ void R_PrecacheLevel(void) {
if (flatpresent[i]) {
lump = firstflat + i;
flatmemory += lumpinfo[lump]->size;
printf("Flat size = %d\n", lumpinfo[lump]->size);
W_CacheLumpNum(lump, PU_CACHE);
}
}
-3
View File
@@ -295,9 +295,6 @@ void R_MakeSpans(int x, int t1, int b1, int t2, int b2) {
}
}
// TMP !!!! DELETE ME
byte* R_GetColumn_LikeIPU(int tex, int col);
extern int numtextures;
//
// R_DrawPlanes