From 683cbbba3ef00f751e839fc63acd07dbdb2537aa Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 10 May 2018 21:28:20 +0200 Subject: [PATCH] Multipass rendering --- core/hw/pvr/ta.cpp | 1 + core/hw/pvr/ta_ctx.h | 29 +++++++++- core/hw/pvr/ta_vtx.cpp | 27 ++++++--- core/rend/gles/gldraw.cpp | 111 ++++++++++++++++++++---------------- core/rend/gles/gles.cpp | 11 +--- core/rend/gles/gles.h | 2 +- core/rend/soft/softrend.cpp | 3 +- 7 files changed, 112 insertions(+), 72 deletions(-) diff --git a/core/hw/pvr/ta.cpp b/core/hw/pvr/ta.cpp index db9fb3f9a..336c1119e 100644 --- a/core/hw/pvr/ta.cpp +++ b/core/hw/pvr/ta.cpp @@ -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; } diff --git a/core/hw/pvr/ta_ctx.h b/core/hw/pvr/ta_ctx.h index cbc7e1f4e..59e8eda6d 100644 --- a/core/hw/pvr/ta_ctx.h +++ b/core/hw/pvr/ta_ctx.h @@ -55,10 +55,12 @@ struct tad_context u8* thd_data; u8* thd_root; u8* thd_old_data; + vector 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 global_param_op; List global_param_pt; List global_param_tr; + List 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(); } }; diff --git a/core/hw/pvr/ta_vtx.cpp b/core/hw/pvr/ta_vtx.cpp index 19d440e6f..65757b76f 100644 --- a/core/hw/pvr/ta_vtx.cpp +++ b/core/hw/pvr/ta_vtx.cpp @@ -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 } diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 6a8f88832..94e0aaff8 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -262,10 +262,9 @@ __forceinline } template -void DrawList(const List& gply) +void DrawList(const List& 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(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(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(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(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(pvrrc.global_param_tr); + if (pvrrc.isAutoSort) + DrawSorted(); + else + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count); #else - if (pvrrc.isAutoSort) - SortPParams(); - DrawList(pvrrc.global_param_tr); + if (pvrrc.isAutoSort) + SortPParams(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count); #endif + } + previous_pass = current_pass; } } diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index bab4e6369..17e9d338e 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -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 diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index a8255d6b8..36688a5bb 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -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(); diff --git a/core/rend/soft/softrend.cpp b/core/rend/soft/softrend.cpp index 8780f69c6..c9b21bd10 100644 --- a/core/rend/soft/softrend.cpp +++ b/core/rend/soft/softrend.cpp @@ -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;