flycast/core/hw/pvr/ta_ctx.h

279 lines
5.6 KiB
C
Raw Normal View History

2013-12-19 17:10:14 +00:00
#pragma once
#include "ta.h"
#include "pvr_regs.h"
// helper for 32 byte aligned memory allocation
void* OS_aligned_malloc(size_t align, size_t size);
// helper for 32 byte aligned memory de-allocation
void OS_aligned_free(void *ptr);
2013-12-19 17:10:14 +00:00
//Vertex storage types
struct Vertex
{
float x,y,z;
u8 col[4];
u8 spc[4];
float u,v;
2018-10-04 08:29:23 +00:00
// Two volumes format
u8 col1[4];
u8 spc1[4];
float u1,v1;
2013-12-19 17:10:14 +00:00
};
struct PolyParam
{
u32 first; //entry index , holds vertex/pos data
u32 count;
//lets see what more :)
u32 texid;
2013-12-19 17:10:14 +00:00
TSP tsp;
TCW tcw;
PCW pcw;
ISP_TSP isp;
float zvZ;
u32 tileclip;
//float zMin,zMax;
2018-10-04 08:29:23 +00:00
TSP tsp1;
TCW tcw1;
u32 texid1;
2013-12-19 17:10:14 +00:00
};
struct ModifierVolumeParam
2013-12-19 17:10:14 +00:00
{
u32 first;
2013-12-19 17:10:14 +00:00
u32 count;
ISP_Modvol isp;
2013-12-19 17:10:14 +00:00
};
struct ModTriangle
{
f32 x0,y0,z0,x1,y1,z1,x2,y2,z2;
};
void decode_pvr_vertex(u32 base,u32 ptr,Vertex* cv);
struct tad_context
{
u8* thd_data;
u8* thd_root;
u8* thd_old_data;
2018-05-14 10:48:22 +00:00
u8 *render_passes[10];
u32 render_pass_count;
2013-12-19 17:10:14 +00:00
void Clear()
{
thd_old_data = thd_data = thd_root;
render_pass_count = 0;
2013-12-19 17:10:14 +00:00
}
void ClearPartial()
{
thd_old_data = thd_data;
thd_data = thd_root;
}
2018-05-10 19:28:20 +00:00
void Continue()
{
render_passes[render_pass_count] = End();
if (render_pass_count < sizeof(render_passes) / sizeof(u8*) - 1)
render_pass_count++;
2018-05-10 19:28:20 +00:00
}
u8* End()
{
return thd_data == thd_root ? thd_old_data : thd_data;
}
void Reset(u8* ptr)
{
thd_data = thd_root = thd_old_data = ptr;
2018-05-14 10:48:22 +00:00
render_pass_count = 0;
}
2013-12-19 17:10:14 +00:00
};
2018-05-10 19:28:20 +00:00
struct RenderPass {
bool autosort;
bool z_clear;
2018-05-10 19:28:20 +00:00
u32 op_count;
u32 mvo_count;
u32 pt_count;
u32 tr_count;
2018-10-04 08:29:23 +00:00
u32 mvo_tr_count;
2018-05-10 19:28:20 +00:00
};
2013-12-19 17:10:14 +00:00
struct rend_context
{
u8* proc_start;
u8* proc_end;
f32 fZ_min;
f32 fZ_max;
2013-12-19 17:10:14 +00:00
bool Overrun;
bool isRTT;
2018-08-26 14:58:10 +00:00
bool isRenderFramebuffer;
2013-12-19 17:10:14 +00:00
double early;
FB_X_CLIP_type fb_X_CLIP;
FB_Y_CLIP_type fb_Y_CLIP;
2018-09-01 10:56:37 +00:00
u32 fog_clamp_min;
u32 fog_clamp_max;
2013-12-19 17:10:14 +00:00
List<Vertex> verts;
List<u32> idx;
List<ModTriangle> modtrig;
List<ModifierVolumeParam> global_param_mvo;
2018-10-04 08:29:23 +00:00
List<ModifierVolumeParam> global_param_mvo_tr;
2013-12-19 17:10:14 +00:00
List<PolyParam> global_param_op;
List<PolyParam> global_param_pt;
List<PolyParam> global_param_tr;
2018-05-10 19:28:20 +00:00
List<RenderPass> render_passes;
2013-12-19 17:10:14 +00:00
void Clear()
{
verts.Clear();
idx.Clear();
global_param_op.Clear();
global_param_pt.Clear();
global_param_tr.Clear();
modtrig.Clear();
global_param_mvo.Clear();
2018-10-04 08:29:23 +00:00
global_param_mvo_tr.Clear();
2018-05-10 19:28:20 +00:00
render_passes.Clear();
2013-12-19 17:10:14 +00:00
Overrun=false;
fZ_min= 1000000.0f;
fZ_max= 1.0f;
2018-08-26 14:58:10 +00:00
isRenderFramebuffer = false;
2013-12-19 17:10:14 +00:00
}
};
#define TA_DATA_SIZE (8 * 1024 * 1024)
2013-12-19 17:10:14 +00:00
//vertex lists
struct TA_context
{
u32 Address;
u32 LastUsed;
cMutex thd_inuse;
cMutex rend_inuse;
tad_context tad;
rend_context rend;
/*
Dreamcast games use up to 20k vtx, 30k idx, 1k (in total) parameters.
at 30 fps, thats 600kvtx (900 stripped)
at 20 fps thats 1.2M vtx (~ 1.8M stripped)
allocations allow much more than that !
some stats:
recv: idx: 33528, vtx: 23451, op: 128, pt: 4, tr: 133, mvo: 14, modt: 342
sc: idx: 26150, vtx: 17417, op: 162, pt: 12, tr: 244, mvo: 6, modt: 2044
doa2le: idx: 47178, vtx: 34046, op: 868, pt: 0, tr: 354, mvo: 92, modt: 976 (overruns)
ika: idx: 46748, vtx: 33818, op: 984, pt: 9, tr: 234, mvo: 10, modt: 16, ov: 0
ct: idx: 30920, vtx: 21468, op: 752, pt: 0, tr: 360, mvo: 101, modt: 732, ov: 0
sa2: idx: 36094, vtx: 24520, op: 1330, pt: 10, tr: 177, mvo: 39, modt: 360, ov: 0
2013-12-19 17:10:14 +00:00
*/
2018-05-10 19:28:20 +00:00
void MarkRend(u32 render_pass)
2013-12-19 17:10:14 +00:00
{
2018-05-14 10:48:22 +00:00
verify(render_pass <= tad.render_pass_count);
2018-05-10 19:28:20 +00:00
rend.proc_start = render_pass == 0 ? tad.thd_root : tad.render_passes[render_pass - 1];
2018-05-14 10:48:22 +00:00
rend.proc_end = render_pass == tad.render_pass_count ? tad.End() : tad.render_passes[render_pass];
2013-12-19 17:10:14 +00:00
}
2018-05-10 19:28:20 +00:00
2013-12-19 17:10:14 +00:00
void Alloc()
{
tad.Reset((u8*)OS_aligned_malloc(32, TA_DATA_SIZE));
2018-04-09 19:11:06 +00:00
2018-10-04 08:29:23 +00:00
rend.verts.InitBytes(4 * 1024 * 1024, &rend.Overrun, "verts"); //up to 4 mb of vtx data/frame = ~ 96k vtx/frame
rend.idx.Init(120 * 1024, &rend.Overrun, "idx"); //up to 120K indexes ( idx have stripification overhead )
rend.global_param_op.Init(8192, &rend.Overrun, "global_param_op");
2018-10-04 08:29:23 +00:00
rend.global_param_pt.Init(4096, &rend.Overrun, "global_param_pt");
rend.global_param_mvo.Init(4096, &rend.Overrun, "global_param_mvo");
rend.global_param_tr.Init(10240, &rend.Overrun, "global_param_tr");
rend.global_param_mvo_tr.Init(4096, &rend.Overrun, "global_param_mvo_tr");
2013-12-19 17:10:14 +00:00
2018-10-04 08:29:23 +00:00
rend.modtrig.Init(16384, &rend.Overrun, "modtrig");
2013-12-19 17:10:14 +00:00
2018-10-04 08:29:23 +00:00
rend.render_passes.Init(sizeof(RenderPass) * 10, &rend.Overrun, "render_passes"); // 10 render passes
2018-05-10 19:28:20 +00:00
2013-12-19 17:10:14 +00:00
Reset();
}
void Reset()
{
verify(tad.End() - tad.thd_root < TA_DATA_SIZE);
2013-12-19 17:10:14 +00:00
tad.Clear();
rend_inuse.Lock();
rend.Clear();
rend.proc_end = rend.proc_start = tad.thd_root;
2013-12-19 17:10:14 +00:00
rend_inuse.Unlock();
}
void Free()
{
verify(tad.End() - tad.thd_root < TA_DATA_SIZE);
OS_aligned_free(tad.thd_root);
2013-12-19 17:10:14 +00:00
rend.verts.Free();
rend.idx.Free();
rend.global_param_op.Free();
rend.global_param_pt.Free();
rend.global_param_tr.Free();
rend.modtrig.Free();
rend.global_param_mvo.Free();
2018-10-04 08:29:23 +00:00
rend.global_param_mvo_tr.Free();
2018-05-10 19:28:20 +00:00
rend.render_passes.Free();
2013-12-19 17:10:14 +00:00
}
};
extern TA_context* ta_ctx;
extern tad_context ta_tad;
extern TA_context* vd_ctx;
extern rend_context vd_rc;
TA_context* tactx_Find(u32 addr, bool allocnew=false);
TA_context* tactx_Pop(u32 addr);
2015-01-16 20:37:30 +00:00
TA_context* tactx_Alloc();
2013-12-19 17:10:14 +00:00
void tactx_Recycle(TA_context* poped_ctx);
2018-10-29 19:02:12 +00:00
void tactx_Term();
2013-12-19 17:10:14 +00:00
/*
Ta Context
Rend Context
*/
#define TACTX_NONE (0xFFFFFFFF)
void SetCurrentTARC(u32 addr);
bool QueueRender(TA_context* ctx);
2013-12-19 17:10:14 +00:00
TA_context* DequeueRender();
void FinishRender(TA_context* ctx);
2013-12-19 17:10:14 +00:00
bool TryDecodeTARC();
void VDecEnd();
//must be moved to proper header
void FillBGP(TA_context* ctx);
bool UsingAutoSort(int pass_number);
2019-02-08 09:22:53 +00:00
bool rend_framePending();