Multipass rendering

This commit is contained in:
Flyinghead 2018-05-10 21:28:20 +02:00
parent 0f92189585
commit 683cbbba3e
7 changed files with 112 additions and 72 deletions

View File

@ -276,6 +276,7 @@ static OnLoad ol_fillfsm(&fill_fsm);
void ta_vtx_ListCont()
{
SetCurrentTARC(TA_ISP_BASE);
ta_tad.Continue();
ta_cur_state=TAS_NS;
}

View File

@ -55,10 +55,12 @@ struct tad_context
u8* thd_data;
u8* thd_root;
u8* thd_old_data;
vector<u8*> render_passes;
void Clear()
{
thd_old_data = thd_data = thd_root;
render_passes.clear();
}
void ClearPartial()
@ -66,6 +68,11 @@ struct tad_context
thd_old_data = thd_data;
thd_data = thd_root;
}
void Continue()
{
render_passes.push_back(thd_data);
}
u8* End()
{
@ -75,10 +82,18 @@ struct tad_context
void Reset(u8* ptr)
{
thd_data = thd_root = thd_old_data = ptr;
render_passes.clear();
}
};
struct RenderPass {
u32 op_count;
u32 mvo_count;
u32 pt_count;
u32 tr_count;
};
struct rend_context
{
u8* proc_start;
@ -104,6 +119,7 @@ struct rend_context
List<PolyParam> global_param_op;
List<PolyParam> global_param_pt;
List<PolyParam> global_param_tr;
List<RenderPass> render_passes;
void Clear()
{
@ -114,6 +130,7 @@ struct rend_context
global_param_tr.Clear();
modtrig.Clear();
global_param_mvo.Clear();
render_passes.Clear();
Overrun=false;
fZ_min= 1000000.0f;
@ -150,11 +167,14 @@ struct TA_context
sa2: idx: 36094, vtx: 24520, op: 1330, pt: 10, tr: 177, mvo: 39, modt: 360, ov: 0
*/
void MarkRend()
void MarkRend(u32 render_pass)
{
rend.proc_start = tad.thd_root;
rend.proc_end = tad.End();
verify(render_pass <= tad.render_passes.size());
rend.proc_start = render_pass == 0 ? tad.thd_root : tad.render_passes[render_pass - 1];
rend.proc_end = render_pass == tad.render_passes.size() ? tad.End() : tad.render_passes[render_pass];
}
void Alloc()
{
tad.Reset((u8*)OS_aligned_malloc(32, 2*1024*1024));
@ -168,6 +188,8 @@ struct TA_context
rend.modtrig.Init(8192,&rend.Overrun);
rend.render_passes.Init(sizeof(RenderPass) * 10, &rend.Overrun); // 10 render passes
Reset();
}
@ -190,6 +212,7 @@ struct TA_context
rend.global_param_tr.Free();
rend.modtrig.Free();
rend.global_param_mvo.Free();
rend.render_passes.Free();
}
};

View File

@ -1444,19 +1444,32 @@ bool ta_parse_vdrc(TA_context* ctx)
vd_rc = vd_ctx->rend;
ta_parse_cnt++;
if (0 == (ta_parse_cnt % ( settings.pvr.ta_skip + 1)))
if (ctx->rend.isRTT || 0 == (ta_parse_cnt % ( settings.pvr.ta_skip + 1)))
{
TAFifo0.vdec_init();
Ta_Dma* ta_data=(Ta_Dma*)vd_rc.proc_start;
Ta_Dma* ta_data_end=((Ta_Dma*)vd_rc.proc_end)-1;
do
for (int pass = 0; pass <= ctx->tad.render_passes.size(); pass++)
{
ta_data =TaCmd(ta_data,ta_data_end);
ctx->MarkRend(pass);
vd_rc.proc_start = ctx->rend.proc_start;
vd_rc.proc_end = ctx->rend.proc_end;
Ta_Dma* ta_data=(Ta_Dma*)vd_rc.proc_start;
Ta_Dma* ta_data_end=((Ta_Dma*)vd_rc.proc_end)-1;
do
{
ta_data =TaCmd(ta_data,ta_data_end);
}
while(ta_data<=ta_data_end);
RenderPass *render_pass = vd_rc.render_passes.Append();
render_pass->op_count = vd_rc.global_param_op.used();
render_pass->mvo_count = vd_rc.global_param_mvo.used();
render_pass->pt_count = vd_rc.global_param_pt.used();
render_pass->tr_count = vd_rc.global_param_tr.used();
}
while(ta_data<=ta_data_end);
rv = true; //whatever
}

View File

@ -262,10 +262,9 @@ __forceinline
}
template <u32 Type, bool SortingEnabled>
void DrawList(const List<PolyParam>& gply)
void DrawList(const List<PolyParam>& gply, int first, int count)
{
PolyParam* params=gply.head();
int count=gply.used();
PolyParam* params = &gply.head()[first];
if (count==0)
@ -311,16 +310,16 @@ bool operator<(const PolyParam &left, const PolyParam &right)
}
//Sort based on min-z of each strip
void SortPParams()
void SortPParams(int first, int count)
{
if (pvrrc.verts.used()==0 || pvrrc.global_param_tr.used()<=1)
if (pvrrc.verts.used() == 0 || count <= 1)
return;
Vertex* vtx_base=pvrrc.verts.head();
u16* idx_base=pvrrc.idx.head();
PolyParam* pp=pvrrc.global_param_tr.head();
PolyParam* pp_end= pp + pvrrc.global_param_tr.used();
PolyParam* pp = &pvrrc.global_param_tr.head()[first];
PolyParam* pp_end = pp + count;
while(pp!=pp_end)
{
@ -499,21 +498,21 @@ void fill_id(u16* d, Vertex* v0, Vertex* v1, Vertex* v2, Vertex* vb)
d[2]=v2-vb;
}
void GenSorted()
void GenSorted(int first, int count)
{
u32 tess_gen=0;
pidx_sort.clear();
if (pvrrc.verts.used()==0 || pvrrc.global_param_tr.used()<=1)
if (pvrrc.verts.used() == 0 || count <= 1)
return;
Vertex* vtx_base=pvrrc.verts.head();
u16* idx_base=pvrrc.idx.head();
PolyParam* pp_base=pvrrc.global_param_tr.head();
PolyParam* pp=pp_base;
PolyParam* pp_end= pp + pvrrc.global_param_tr.used();
PolyParam* pp_base = &pvrrc.global_param_tr.head()[first];
PolyParam* pp = pp_base;
PolyParam* pp_end = pp + count;
Vertex* vtx_arr=vtx_base+idx_base[pp->first];
vtx_sort_base=vtx_base;
@ -966,9 +965,9 @@ void SetupModvolVBO()
glDisableVertexAttribArray(VERTEX_COL_OFFS_ARRAY);
glDisableVertexAttribArray(VERTEX_COL_BASE_ARRAY);
}
void DrawModVols()
void DrawModVols(int first, int count)
{
if (pvrrc.modtrig.used()==0 /*|| GetAsyncKeyState(VK_F4)*/)
if (count == 0 /*|| GetAsyncKeyState(VK_F4)*/)
return;
SetupModvolVBO();
@ -986,7 +985,7 @@ void DrawModVols()
{
//simply draw the volumes -- for debugging
SetCull(0);
glDrawArrays(GL_TRIANGLES,0,pvrrc.modtrig.used()*3);
glDrawArrays(GL_TRIANGLES, first, count * 3);
SetupMainVBO();
}
else
@ -1021,7 +1020,7 @@ void DrawModVols()
#endif
glStencilMask(0x1);
SetCull(0);
glDrawArrays(GL_TRIANGLES,0,pvrrc.modtrig.used()*3);
glDrawArrays(GL_TRIANGLES, first, count * 3);
}
else if (true)
{
@ -1031,8 +1030,8 @@ void DrawModVols()
u32 mod_base=0; //cur start triangle
u32 mod_last=0; //last merge
u32 cmv_count=(pvrrc.global_param_mvo.used()-1);
ISP_Modvol* params=pvrrc.global_param_mvo.head();
u32 cmv_count = count - 1;
ISP_Modvol* params = &pvrrc.global_param_mvo.head()[first];
//ISP_Modvol
for (u32 cmv=0;cmv<cmv_count;cmv++)
@ -1117,46 +1116,60 @@ void DrawStrips()
SetupMainVBO();
//Draw the strips !
//initial state
glDisable(GL_BLEND); glCheck();
glEnable(GL_DEPTH_TEST);
//We use sampler 0
glActiveTexture(GL_TEXTURE0);
//Opaque
//Nothing extra needs to be setup here
/*if (!GetAsyncKeyState(VK_F1))*/
DrawList<ListType_Opaque,false>(pvrrc.global_param_op);
RenderPass previous_pass = {0};
for (int render_pass = 0; render_pass < pvrrc.render_passes.used(); render_pass++) {
const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass];
DrawModVols();
//initial state
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
//Alpha tested
//setup alpha test state
/*if (!GetAsyncKeyState(VK_F2))*/
DrawList<ListType_Punch_Through,false>(pvrrc.global_param_pt);
glClearDepthf(0.f);
glDepthMask(GL_TRUE);
glStencilMask(0xFF);
glClear(GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCheck();
//Opaque
//Nothing extra needs to be setup here
/*if (!GetAsyncKeyState(VK_F1))*/
DrawList<ListType_Opaque,false>(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count);
DrawModVols(previous_pass.mvo_count, current_pass.mvo_count);
//Alpha tested
//setup alpha test state
/*if (!GetAsyncKeyState(VK_F2))*/
DrawList<ListType_Punch_Through,false>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count);
//Alpha blended
//Setup blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/*if (!GetAsyncKeyState(VK_F3))*/
{
/*
if (UsingAutoSort())
SortRendPolyParamList(pvrrc.global_param_tr);
else
*/
//Alpha blended
//Setup blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/*if (!GetAsyncKeyState(VK_F3))*/
{
/*
if (UsingAutoSort())
SortRendPolyParamList(pvrrc.global_param_tr);
else
*/
if (pvrrc.isAutoSort)
GenSorted(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
#if TRIG_SORT
if (pvrrc.isAutoSort)
DrawSorted();
else
DrawList<ListType_Translucent,false>(pvrrc.global_param_tr);
if (pvrrc.isAutoSort)
DrawSorted();
else
DrawList<ListType_Translucent,false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
#else
if (pvrrc.isAutoSort)
SortPParams();
DrawList<ListType_Translucent,true>(pvrrc.global_param_tr);
if (pvrrc.isAutoSort)
SortPParams(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
DrawList<ListType_Translucent,true>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
#endif
}
previous_pass = current_pass;
}
}

View File

@ -58,8 +58,6 @@ Tile clip
#include "rend/rend.h"
#include "hw/pvr/Renderer_if.h"
void GenSorted();
float fb_scale_x,fb_scale_y;
float scale_x, scale_y;
@ -1432,7 +1430,6 @@ void OSD_DRAW()
bool ProcessFrame(TA_context* ctx)
{
ctx->rend_inuse.Lock();
ctx->MarkRend();
if (KillTex)
{
@ -1752,13 +1749,7 @@ bool RenderFrame()
else
glClearColor(0,0,0,1.0f);
glClearDepthf(0.f); glCheck();
glStencilMask(0xFF); glCheck();
glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glCheck();
if (UsingAutoSort())
GenSorted();
glClear(GL_COLOR_BUFFER_BIT); glCheck();
//move vertex to gpu

View File

@ -115,7 +115,7 @@ struct text_info {
text_info raw_GetTexture(TSP tsp, TCW tcw);
void CollectCleanup();
void DoCleanup();
void SortPParams();
void SortPParams(int first, int count);
void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt);
void ReadRTTBuffer();

View File

@ -824,7 +824,6 @@ struct softrend : Renderer
return false;
ctx->rend_inuse.Lock();
ctx->MarkRend();
if (!ta_parse_vdrc(ctx))
return false;
@ -866,7 +865,7 @@ struct softrend : Renderer
return false;
if (pvrrc.isAutoSort)
SortPParams();
SortPParams(0, pvrrc.global_param_tr.used());
int tcount = omp_get_num_procs() - 1;
if (tcount == 0) tcount = 1;