Merge branch 'skmp/update-refsw2-tacore' into 'main'

koshle: Update refsw2 and tacore

See merge request skmp/dca3-game!99
This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis
2025-05-06 20:20:18 +00:00
9 changed files with 2083 additions and 430 deletions

View File

@@ -182,7 +182,8 @@ struct pvr2_ta_status {
int32_t state;
int32_t width, height; /* Tile resolution, ie 20x15 */
int32_t tilelist_dir; /* Growth direction of the tilelist, 0 = up, 1 = down */
uint32_t tilelist_size; /* Size of the tilelist segments */
// uint32_t tilelist_size; /* Size of the tilelist segments */
// this needs to be current_tile_size
uint32_t tilelist_start; /* Initial address of the tilelist */
uint32_t polybuf_start; /* Initial bank address of the polygon buffer (ie &0x00F00000) */
int32_t current_vertex_type;
@@ -208,6 +209,9 @@ struct pvr2_ta_status {
struct tile_bounds last_triangle_bounds;
struct pvr2_ta_vertex poly_vertex[8];
uint32_t debug_output;
bool modifier_last_volume;
struct tile_bounds modifier_bounds;
};
static struct pvr2_ta_status ta_status;
@@ -253,13 +257,9 @@ void lxd_ta_init(u8* vram) {
ta_status.clip.y2 = ta_status.height-1;
uint32_t control = TA_ALLOC_CTRL; //MMIO_READ( PVR2, TA_TILECFG );
ta_status.tilelist_dir = (control >> 20) & 0x01;
ta_status.tilelist_size = tilematrix_sizes[ (control & 0x03) ];
TA_ISP_CURRENT = TA_ISP_BASE;
//MMIO_WRITE( PVR2, TA_POLYPOS, MMIO_READ( PVR2, TA_POLYBASE ) );
uint32_t plistpos = TA_NEXT_OPB_INIT >> 2; //MMIO_READ( PVR2, TA_LISTBASE )
if( ta_status.tilelist_dir == TA_GROW_DOWN ) {
plistpos -= ta_status.tilelist_size;
}
TA_NEXT_OPB = plistpos;
//MMIO_WRITE( PVR2, TA_LISTPOS, plistpos );
ta_status.tilelist_start = plistpos;
@@ -433,7 +433,9 @@ static uint32_t ta_alloc_tilelist( uint32_t reference ) {
uint32_t limit = TA_OL_LIMIT >> 2;//MMIO_READ( PVR2, TA_LISTEND ) >> 2;
uint32_t newposn;
if( ta_status.tilelist_dir == TA_GROW_DOWN ) {
newposn = posn - ta_status.tilelist_size;
// printf("**TA WARNING**: Allocating tilelist in GROW_DOWN mode\n");
posn -= ta_status.current_tile_size;
newposn = posn;
if( posn == limit ) {
PVRRAM(posn<<2) = 0xF0000000;
PVRRAM(reference) = 0xE0000000 | (posn<<2);
@@ -442,7 +444,7 @@ static uint32_t ta_alloc_tilelist( uint32_t reference ) {
PVRRAM(reference) = 0xE0000000 | (posn<<2);
return TA_NO_ALLOC;
} else if( newposn <= limit ) {
} else if( newposn <= (limit + ta_status.tilelist_size) ) {
} else if( newposn <= (limit + ta_status.current_tile_size) ) {
// asic_RaiseInterrupt(holly_MATR_NOMEM);
pvr_queue_interrupt(ASIC_EVT_PVR_OPB_OUTOFMEM);
printf("TA error: holly_MATR_NOMEM. Interrupt raised\n");
@@ -456,7 +458,7 @@ static uint32_t ta_alloc_tilelist( uint32_t reference ) {
PVRRAM(reference) = 0xE0000000 | (posn<<2);
return posn << 2;
} else {
newposn = posn + ta_status.tilelist_size;
newposn = posn + ta_status.current_tile_size;
if( posn == limit ) {
PVRRAM(posn<<2) = 0xF0000000;
PVRRAM(reference) = 0xE0000000 | (posn<<2);
@@ -465,7 +467,7 @@ static uint32_t ta_alloc_tilelist( uint32_t reference ) {
PVRRAM(reference) = 0xE0000000 | (posn<<2);
return TA_NO_ALLOC;
} else if( newposn >= limit ) {
} else if( newposn >= (limit - ta_status.tilelist_size) ) {
} else if( newposn >= (limit - ta_status.current_tile_size) ) {
// asic_RaiseInterrupt(holly_MATR_NOMEM);
pvr_queue_interrupt(ASIC_EVT_PVR_OPB_OUTOFMEM);
printf("TA error: holly_MATR_NOMEM. Interrupt raised\n");
@@ -621,6 +623,17 @@ static void ta_commit_polygon( ) {
if( polygon_bound.y1 < 0 ) polygon_bound.y1 = 0;
if( polygon_bound.y2 >= ta_status.height ) polygon_bound.y2 = ta_status.height-1;
if (ta_status.current_vertex_type == TA_VERTEX_MOD_VOLUME) {
ta_status.modifier_bounds.x1 = MIN(ta_status.modifier_bounds.x1, polygon_bound.x1);
ta_status.modifier_bounds.x2 = MAX(ta_status.modifier_bounds.x2, polygon_bound.x2);
ta_status.modifier_bounds.y1 = MIN(ta_status.modifier_bounds.y1, polygon_bound.y1);
ta_status.modifier_bounds.y2 = MAX(ta_status.modifier_bounds.y2, polygon_bound.y2);
if (ta_status.modifier_last_volume) {
polygon_bound = ta_status.modifier_bounds;
}
}
/* Set the "single tile" flag if it's entirely contained in 1 tile */
if( polygon_bound.x1 == polygon_bound.x2 &&
polygon_bound.y1 == polygon_bound.y2 ) {
@@ -843,6 +856,14 @@ static void ta_parse_modifier_context( union ta_data *data ) {
ta_status.vertex_count = 0;
ta_status.max_vertex = 3;
ta_status.poly_pointer = 0;
if (ta_status.modifier_last_volume) {
ta_status.modifier_bounds.x1 = INT_MAX/32;
ta_status.modifier_bounds.y1 = INT_MAX/32;
ta_status.modifier_bounds.x2 = -1;
ta_status.modifier_bounds.y2 = -1;
}
ta_status.modifier_last_volume = data[0].i & TA_POLYCMD_FULLMOD;
}
/**
@@ -1006,7 +1027,11 @@ static void ta_parse_vertex( union ta_data *data ) {
vertex++;
vertex->x = data[7].f;
ta_status.vertex_count += 2;
ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;
if (ta_status.current_vertex_type == TA_VERTEX_SPRITE || ta_status.current_vertex_type == TA_VERTEX_TEX_SPRITE) {
ta_status.state = STATE_EXPECT_END_VERTEX_BLOCK2;
} else {
ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;
}
break;
}
ta_status.vertex_count++;

View File

@@ -14,9 +14,9 @@
#endif
u32 detwiddle[2][11][1024];
u8 BM_SIN90[256];
u8 BM_COS90[256];
u8 BM_COS360[256];
s8 BM_SIN90[256];
s8 BM_COS90[256];
s8 BM_COS360[256];
//input : address in the yyyyyxxxxx format
//output : address in the xyxyxyxy format
@@ -70,9 +70,9 @@ void BuildTables()
}
for (int i = 0; i < 256; i++) {
BM_SIN90[i] = 255 * sinf((i / 256.0f) * (M_PI / 2));
BM_COS90[i] = 255 * cosf((i / 256.0f) * (M_PI / 2));
BM_COS360[i] = 255 * cosf((i / 256.0f) * (2 * M_PI));
BM_SIN90[i] = 127 * sinf((i / 256.0f) * (M_PI / 2));
BM_COS90[i] = 127 * cosf((i / 256.0f) * (M_PI / 2));
BM_COS360[i] = 127 * cosf((i / 256.0f) * (2 * M_PI));
}
}

View File

@@ -8,9 +8,9 @@
#include <algorithm>
extern u32 detwiddle[2][11][1024];
extern u8 BM_SIN90[256];
extern u8 BM_COS90[256];
extern u8 BM_COS360[256];
extern s8 BM_SIN90[256];
extern s8 BM_COS90[256];
extern s8 BM_COS360[256];
void BuildTables();

1456
vendor/emu/refsw/gentable.h vendored Normal file

File diff suppressed because it is too large Load Diff

90
vendor/emu/refsw/gentable.py vendored Normal file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env python3
import itertools
def generate_table(name, parameters):
"""
Generates C++ code for PixelFlush_tsp_table given parameter ranges.
:param parameters: tuple of ints, the range for each template parameter
:return: string containing the C++ table declaration and initializer
"""
num_params = len(parameters)
# Construct the table dimensions
dims = ''.join(f'[{p}]' for p in parameters)
# Start building the initializer as a list of strings
lines = []
def recurse(level, indices, indent):
if level == num_params:
# Leaf: generate function pointer
params_list = ', '.join(str(i) for i in indices)
lines.append(f"{indent}&{name}<{params_list}>,")
else:
# Open brace for this dimension
lines.append(f"{indent}{{")
for i in range(parameters[level]):
recurse(level + 1, indices + [i], indent + ' ')
# Close brace
if level != 0:
lines.append(f"{indent}}},")
else:
lines.append(f"{indent}}}")
# Table declaration
decl = f"{name}_fp {name}_table{dims} ="
lines.append(decl)
recurse(0, [], ' ')
lines.append(';')
return '\n'.join(lines)
if __name__ == '__main__':
# Example usage: each bool has 2 possibilities, some enums have more
bitwidths = (
1, # [pp_AlphaTest]
1, # [entry->params.tsp[two_voume_index].UseAlpha]
1, # [entry->params.isp.Texture]
1, # [entry->params.isp.Offset]
1, # [entry->params.tsp[two_voume_index].ColorClamp]
2, # [entry->params.tsp[two_voume_index].FogCtrl]
1, # [FPU_SHAD_SCALE.intensity_shadow]
)
code = generate_table("PixelFlush_tsp", tuple(1 << bw for bw in bitwidths))
print(code)
bitwidths = (
1, # [entry->params.tsp[two_voume_index].IgnoreTexA]
1, # [entry->params.tsp[two_voume_index].ClampU]
1, # [entry->params.tsp[two_voume_index].ClampV]
1, # [entry->params.tsp[two_voume_index].FlipU]
1, # [entry->params.tsp[two_voume_index].FlipV]
2, # [entry->params.tsp[two_voume_index].FilterMode]
)
code = generate_table("TextureFilter", tuple(1 << bw for bw in bitwidths))
print(code)
bitwidths = (
1, # [entry->params.isp.Texture]
1, # [entry->params.isp.Offset]
2, # [entry->params.tsp[two_voume_index].ShadInstr ]
)
code = generate_table("ColorCombiner", tuple(1 << bw for bw in bitwidths))
print(code)
bitwidths = (
1, # [entry->params.tsp[two_voume_index].SrcSelect]
1, # [entry->params.tsp[two_voume_index].DstSelect]
3, # [entry->params.tsp[two_voume_index].SrcInstr]
3, # [entry->params.tsp[two_voume_index].DstInstr]
)
code = generate_table("BlendingUnit", tuple(1 << bw for bw in bitwidths))
print(code)
bitwidths = (
1, # [entry->params.tcw[two_voume_index].VQ_Comp]
1, # [entry->params.tcw[two_voume_index].MipMapped]
1, # [entry->params.tcw[two_voume_index].ScanOrder]
1, # [entry->params.tcw[two_voume_index].StrideSel]
3, # [entry->params.tcw[two_voume_index].PixelFmt]
)
code = generate_table("TextureFetch", tuple(1 << bw for bw in bitwidths))
print(code)

View File

@@ -81,34 +81,16 @@
#include "refsw_tile.h"
#define JLOG(...)
#define JLOG2(...)
#define V(x) x
void log_vertex(const Vertex& v) {
JLOG(ll,
V(v.x), V(v.y), V(v.z),
V(v.col[0]), V(v.col[1]), V(v.col[2]), V(v.col[3]), V(v.spc[0]), V(v.spc[1]), V(v.spc[2]), V(v.spc[3]), V(v.u), V(v.v),
V(v.col1[0]), V(v.col1[1]), V(v.col1[2]), V(v.col1[3]), V(v.spc1[0]), V(v.spc1[1]), V(v.spc1[2]), V(v.spc1[3]), V(v.u1), V(v.v1)
);
}
/*
Main renderer class
*/
void RenderTriangle(RenderMode render_mode, DrawParameters* params, parameter_tag_t tag, const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex* v4, taRECT* area)
{
JLOG(ll, V(render_mode), V(tag), "tsp0", params->tsp[0].full, "tcw0", params->tcw[0].full, "tsp1", params->tsp[1].full, "tcw1", params->tcw[1].full);
{
RasterizeTriangle_table[render_mode](params, tag, v1, v2, v3, v4, area);
log_vertex(v1);
log_vertex(v2);
log_vertex(v3);
if (v4) {
log_vertex(*v4);
if (render_mode == RM_TRANSLUCENT_PRESORT) {
RenderParamTags<RM_TRANSLUCENT_PRESORT>(area->left, area->top);
}
RasterizeTriangle(render_mode, params, tag, v1, v2, v3, v4, area);
if (render_mode == RM_MODIFIER)
{
@@ -138,6 +120,7 @@ u32 ReadRegionArrayEntry(u32 base, RegionArrayEntry* entry)
u32 rv;
if (fmt_v1)
{
entry->control.pre_sort = ISP_FEED_CFG.pre_sort;
entry->puncht.full = 0x80000000;
rv = 5 * 4;
}
@@ -160,13 +143,13 @@ u32 ReadRegionArrayEntry(u32 base, RegionArrayEntry* entry)
}
ISP_BACKGND_T_type CoreTagFromDesc(u32 cache_bypass, u32 shadow, u32 skip, u32 param_offs_in_words, u32 tag_offset) {
ISP_BACKGND_T_type rv {
.tag_offset = tag_offset,
.param_offs_in_words = param_offs_in_words,
.skip = skip,
.shadow = shadow,
.cache_bypass = cache_bypass
};
ISP_BACKGND_T_type rv;
rv.full = 0;
rv.tag_offset = tag_offset;
rv.param_offs_in_words = param_offs_in_words;
rv.skip = skip;
rv.shadow = shadow;
rv.cache_bypass = cache_bypass;
return rv;
}
@@ -174,8 +157,6 @@ ISP_BACKGND_T_type CoreTagFromDesc(u32 cache_bypass, u32 shadow, u32 skip, u32 p
// render a triangle strip object list entry
void RenderTriangleStrip(RenderMode render_mode, ObjectListEntry obj, taRECT* rect)
{
JLOG(ll, V(render_mode), "obj", obj.full);
Vertex vtx[8];
DrawParameters params;
@@ -204,7 +185,6 @@ void RenderTriangleStrip(RenderMode render_mode, ObjectListEntry obj, taRECT* re
// render a triangle array object list entry
void RenderTriangleArray(RenderMode render_mode, ObjectListEntry obj, taRECT* rect)
{
JLOG(ll, V(render_mode), "obj", obj.full);
auto triangles = obj.tarray.prims + 1;
u32 param_base = PARAM_BASE & 0xF00000;
@@ -222,8 +202,6 @@ void RenderTriangleArray(RenderMode render_mode, ObjectListEntry obj, taRECT* re
parameter_tag_t tag = CoreTagFromDesc(params.isp.CacheBypass, obj.tstrip.shadow, obj.tstrip.skip, (tag_address - param_base)/4, 0).full;
assert(!(tag & TAG_INVALID));
RenderTriangle(render_mode, &params, tag, vtx[0], vtx[1], vtx[2], nullptr, rect);
}
}
@@ -231,8 +209,6 @@ void RenderTriangleArray(RenderMode render_mode, ObjectListEntry obj, taRECT* re
// render a quad array object list entry
void RenderQuadArray(RenderMode render_mode, ObjectListEntry obj, taRECT* rect)
{
JLOG(ll, V(render_mode), "obj", obj.full);
auto quads = obj.qarray.prims + 1;
u32 param_base = PARAM_BASE & 0xF00000;
@@ -301,22 +277,12 @@ void RenderCORE() {
}
u32 base = REGION_BASE;
JLOG(ll, V(REGION_BASE));
RegionArrayEntry entry;
// Parse region array
do {
auto step = ReadRegionArrayEntry(base, &entry);
JLOG2(llrrae, "ReadRegionArrayEntry", V(base),
"control", entry.control.full,
"opaque", entry.opaque.full,
"opaque_mod", entry.opaque_mod.full,
"trans", entry.trans.full,
"trans_mod", entry.trans_mod.full,
"puncht", entry.puncht.full);
base += step;
taRECT rect;
@@ -328,6 +294,7 @@ void RenderCORE() {
parameter_tag_t bgTag;
ClearFpuCache();
// register BGPOLY to fpu
{
bgTag = ISP_BACKGND_T.full;
@@ -338,85 +305,102 @@ void RenderCORE() {
{
// Clear Param + Z + stencil buffers
ClearBuffers(bgTag, ISP_BACKGND_D.f, 0);
} else {
ClearParamStatusBuffer();
}
// Render OPAQ to TAGS
if (!entry.opaque.empty)
{
JLOG2(llo, "opaque", V(entry.opaque.ptr_in_words));
RenderObjectList(RM_OPAQUE, entry.opaque.ptr_in_words * 4, &rect);
if (!entry.opaque_mod.empty)
{
RenderObjectList(RM_MODIFIER, entry.opaque_mod.ptr_in_words * 4, &rect);
}
}
// Render TAGS to ACCUM
RenderParamTags(RM_OPAQUE, rect.left, rect.top);
RenderParamTags<RM_OPAQUE>(rect.left, rect.top);
// render PT to TAGS
if (!entry.puncht.empty)
{
PeelBuffersPTInitial(FLT_MAX);
ClearMoreToDraw();
do {
// Render to TAGS
RenderObjectList(RM_PUNCHTHROUGH_PASS0, entry.puncht.ptr_in_words * 4, &rect);
// keep reference Z buffer
PeelBuffersPT();
// Render TAGS to ACCUM, making Z holes as-needed
RenderParamTags<RM_PUNCHTHROUGH_PASS0>(rect.left, rect.top);
while (GetMoreToDraw()) {
ClearMoreToDraw();
// Render to TAGS
{
JLOG2(llo, "puncht", V(entry.puncht.ptr_in_words));
RenderObjectList(RM_PUNCHTHROUGH, entry.puncht.ptr_in_words * 4, &rect);
}
RenderObjectList(RM_PUNCHTHROUGH_PASSN, entry.puncht.ptr_in_words * 4, &rect);
if (!GetMoreToDraw())
break;
ClearMoreToDraw();
// keep reference Z buffer
PeelBuffersPT();
// Render TAGS to ACCUM, making Z holes as-needed
RenderParamTags(RM_PUNCHTHROUGH, rect.left, rect.top);
// Copy TAGB=TAGA buffers, clear TAGA
PeelBuffersPTAfterHoles();
} while (GetMoreToDraw() != 0);
}
//TODO: Actually render OPAQ modvol affected pixels
if (!entry.opaque_mod.empty)
{
JLOG2(llo, "opaque_mod", V(entry.opaque_mod.ptr_in_words));
RenderObjectList(RM_MODIFIER, entry.opaque_mod.ptr_in_words * 4, &rect);
RenderParamTags(RM_OP_PT_MV, rect.left, rect.top);
RenderParamTags<RM_PUNCHTHROUGH_PASS0>(rect.left, rect.top);
}
if (!entry.opaque_mod.empty)
{
RenderObjectList(RM_MODIFIER, entry.opaque_mod.ptr_in_words * 4, &rect);
RenderParamTags<RM_PUNCHTHROUGH_MV>(rect.left, rect.top);
}
}
// layer peeling rendering
if (!entry.trans.empty)
{
// clear the param buffer
ClearParamBuffer(TAG_INVALID);
if (entry.control.pre_sort) {
// clear the param buffer
ClearParamStatusBuffer();
do
{
// prepare for a new pass
ClearMoreToDraw();
// render to TAGS
{
RenderObjectList(RM_TRANSLUCENT_PRESORT, entry.trans.ptr_in_words * 4, &rect);
}
// what happens with modvols here?
// if (!entry.trans_mod.empty)
// {
// RenderObjectList(RM_MODIFIER, entry.trans_mod.ptr_in_words * 4, &rect);
// }
} else {
do
{
// prepare for a new pass
ClearMoreToDraw();
if (!ISP_FEED_CFG.pre_sort) {
// copy depth test to depth reference buffer, clear depth test buffer, clear stencil
PeelBuffers(FLT_MAX, 0);
}
// render to TAGS
{
JLOG2(llo, "trans", V(entry.trans.ptr_in_words));
RenderObjectList(RM_TRANSLUCENT, entry.trans.ptr_in_words * 4, &rect);
}
// render to TAGS
{
RenderObjectList(RM_TRANSLUCENT_AUTOSORT, entry.trans.ptr_in_words * 4, &rect);
}
if (!entry.trans_mod.empty)
{
JLOG2(llo, "trans_mod", V(entry.trans_mod.ptr_in_words));
RenderObjectList(RM_MODIFIER, entry.trans_mod.ptr_in_words * 4, &rect);
}
if (!entry.trans_mod.empty)
{
RenderObjectList(RM_MODIFIER, entry.trans_mod.ptr_in_words * 4, &rect);
}
// render TAGS to ACCUM
// also marks TAGS as invalid, but keeps the index for coplanar sorting
RenderParamTags(RM_TRANSLUCENT, rect.left, rect.top);
} while (GetMoreToDraw() != 0);
// render TAGS to ACCUM
RenderParamTags<RM_TRANSLUCENT_AUTOSORT>(rect.left, rect.top);
} while (GetMoreToDraw() != 0);
}
}
// Copy to vram
@@ -469,9 +453,6 @@ void RenderCORE() {
}
}
}
// clear the tsp cache
ClearFpuEntries();
} while (!entry.control.last_region);
}

View File

@@ -26,13 +26,23 @@ struct DrawParameters
enum RenderMode {
RM_OPAQUE,
RM_PUNCHTHROUGH,
RM_OP_PT_MV, // OP and PT with modvol
RM_TRANSLUCENT,
RM_PUNCHTHROUGH_PASS0,
RM_PUNCHTHROUGH_PASSN,
RM_PUNCHTHROUGH_MV, // PT MODVOL 2nd pass
RM_TRANSLUCENT_AUTOSORT,
RM_TRANSLUCENT_PRESORT,
RM_MODIFIER,
};
#define TAG_INVALID (1 << 31)
struct TagState {
union {
struct {
bool valid: 1;
bool rendered: 1;
};
uint8_t raw;
};
};
typedef u32 parameter_tag_t;

File diff suppressed because it is too large Load Diff

View File

@@ -39,6 +39,10 @@ struct PlaneStepper3
float C = ((v2.x - v1.x) * (v3.y - v1.y) - (v3.x - v1.x) * (v2.y - v1.y));
if (C == 0) {
C = 1; // avoid divide by zero
}
ddx = -Aa / C;
ddy = -Ba / C;
@@ -54,6 +58,16 @@ struct PlaneStepper3
{
return Ip(x, y) * W;
}
float IpU8(float x, float y, float W) const
{
float rv = Ip(x, y, W);
if (rv < 0) rv = 0;
if (rv > 255) rv = 255;
return rv;
}
};
/*
@@ -87,8 +101,8 @@ struct IPs3
}
if (TwoVolumes) {
U[1].Setup(rect, v1, v2, v3, v1.u * v1.z, v2.u1 * v2.z, v3.u1 * v3.z);
V[1].Setup(rect, v1, v2, v3, v1.v * v1.z, v2.v1 * v2.z, v3.v1 * v3.z);
U[1].Setup(rect, v1, v2, v3, v1.u1 * v1.z, v2.u1 * v2.z, v3.u1 * v3.z);
V[1].Setup(rect, v1, v2, v3, v1.v1 * v1.z, v2.v1 * v2.z, v3.v1 * v3.z);
if (params->isp.Gouraud) {
for (int i = 0; i < 4; i++)
Col[1][i].Setup(rect, v1, v2, v3, v1.col1[i] * v1.z, v2.col1[i] * v2.z, v3.col1[i] * v3.z);
@@ -128,10 +142,9 @@ extern u32 colorBuffer1 [MAX_RENDER_PIXELS];
extern const char* dump_textures;
void ClearBuffers(u32 paramValue, float depthValue, u32 stencilValue);
void ClearParamBuffer(parameter_tag_t paramValue);
void ClearParamStatusBuffer();
void PeelBuffers(float depthValue, u32 stencilValue);
void PeelBuffersPT();
void PeelBuffersPTAfterHoles();
void PeelBuffersPTInitial(float depthValue);
void SummarizeStencilOr();
void SummarizeStencilAnd();
@@ -140,31 +153,29 @@ bool GetMoreToDraw();
// Render to ACCUM from TAG buffer
// TAG holds references to triangles, ACCUM is the tile framebuffer
void RenderParamTags(RenderMode rm, int tileX, int tileY);
void ClearFpuEntries();
template<RenderMode rm>
void RenderParamTags(int tileX, int tileY);
f32 f16(u16 v);
inline __attribute__((always_inline)) f32 f16(u16 v)
{
u32 z=v<<16;
return *(f32*)&z;
}
//decode a vertex in the native pvr format
void decode_pvr_vertex(DrawParameters* params, pvr32addr_t ptr,Vertex* cv, u32 shadow);
// decode an object (params + vertexes)
u32 decode_pvr_vertices(DrawParameters* params, pvr32addr_t base, u32 skip, u32 two_volumes, Vertex* vtx, int count, int offset);
FpuEntry GetFpuEntry(taRECT *rect, RenderMode render_mode, ISP_BACKGND_T_type core_tag);
const FpuEntry& GetFpuEntry(taRECT *rect, RenderMode render_mode, ISP_BACKGND_T_type core_tag);
// Lookup/create cached TSP parameters, and call PixelFlush_tsp
bool PixelFlush_tsp(bool pp_AlphaTest, FpuEntry* entry, float x, float y, u32 index, float invW, bool InVolume);
bool PixelFlush_tsp(bool pp_AlphaTest, const FpuEntry* entry, float x, float y, u32 index, float invW, bool InVolume);
// Rasterize a single triangle to ISP (or ISP+TSP for PT)
void RasterizeTriangle(RenderMode render_mode, DrawParameters* params, parameter_tag_t tag, const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex* v4, taRECT* area);
extern void (*RasterizeTriangle_table[])(DrawParameters* params, parameter_tag_t tag, const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex* v4, taRECT* area);
u8* GetColorOutputBuffer();
// Implement the full texture/shade pipeline for a pixel
bool PixelFlush_tsp(
bool pp_UseAlpha, bool pp_Texture, bool pp_Offset, bool pp_ColorClamp, u32 pp_FogCtrl, bool pp_IgnoreAlpha, bool pp_ClampU, bool pp_ClampV, bool pp_FlipU, bool pp_FlipV, u32 pp_FilterMode, u32 pp_ShadInstr, bool pp_AlphaTest, u32 pp_SrcSel, u32 pp_DstSel, u32 pp_SrcInst, u32 pp_DstInst,
const FpuEntry *entry, float x, float y, float W, bool InVolume, u32 index);
// Depth processing for a pixel -- render_mode 0: OPAQ, 1: PT, 2: TRANS
void PixelFlush_isp(RenderMode render_mode, u32 depth_mode, u32 ZWriteDis, float x, float y, float invW, u32 index, parameter_tag_t tag);
/*
Main renderer class
@@ -180,4 +191,5 @@ void RenderTriangleArray(RenderMode render_mode, ObjectListEntry obj, taRECT* re
void RenderQuadArray(RenderMode render_mode, ObjectListEntry obj, taRECT* rect);
void RenderObjectList(RenderMode render_mode, pvr32addr_t base, taRECT* rect);
void RenderCORE();
void Hackpresent();
void Hackpresent();
void ClearFpuCache();