diff --git a/core/hw/pvr/ta_vtx.cpp b/core/hw/pvr/ta_vtx.cpp index 55cc40333..66a4c2adc 100644 --- a/core/hw/pvr/ta_vtx.cpp +++ b/core/hw/pvr/ta_vtx.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include #define TACALL DYNACALL #ifdef NDEBUG @@ -1274,6 +1276,78 @@ static void fix_texture_bleeding(const List *list) } } +static bool operator<(const PolyParam& left, const PolyParam& right) +{ + return left.zvZ < right.zvZ; +} + +static void sortPolyParams(List *polys, int first, int end, rend_context* ctx) +{ + if (end - first <= 1) + return; + + Vertex *vtx_base = ctx->verts.head(); + + PolyParam *pp = &polys->head()[first]; + PolyParam *pp_end = &polys->head()[end]; + + while (pp != pp_end) + { + if (pp->count < 3) + { + pp->zvZ = 0; + } + else + { + Vertex *vtx = &vtx_base[pp->first]; + Vertex *vtx_end = &vtx_base[pp->first + pp->count]; + + if (pp->isNaomi2()) + { + glm::mat4 mvMat = pp->mvMatrix != nullptr ? glm::make_mat4(pp->mvMatrix) : glm::mat4(1); + glm::vec3 min{ 1e38f, 1e38f, 1e38f }; + glm::vec3 max{ -1e38f, -1e38f, -1e38f }; + while (vtx != vtx_end) + { + glm::vec3 pos{ vtx->x, vtx->y, vtx->z }; + min = glm::min(min, pos); + max = glm::max(max, pos); + vtx++; + } + glm::vec4 center((min + max) / 2.f, 1); + glm::vec4 extents(max - glm::vec3(center), 0); + // transform + center = mvMat * center; + glm::vec3 extentX = mvMat * glm::vec4(extents.x, 0, 0, 0); + glm::vec3 extentY = mvMat * glm::vec4(0, extents.y, 0, 0); + glm::vec3 extentZ = mvMat * glm::vec4(0, 0, extents.z, 0); + // new AA extents + glm::vec3 newExtent = glm::abs(extentX) + glm::abs(extentY) + glm::abs(extentZ); + + min = glm::vec3(center) - newExtent; + max = glm::vec3(center) + newExtent; + + // project + pp->zvZ = -1 / std::min(min.z, max.z); + } + else + { + u32 zv = 0xFFFFFFFF; + while (vtx != vtx_end) + { + zv = std::min(zv, (u32&)vtx->z); + vtx++; + } + + pp->zvZ = (f32&)zv; + } + } + pp++; + } + + std::stable_sort(&polys->head()[first], pp_end); +} + static bool ta_parse_vdrc(TA_context* ctx) { ctx->rend_inuse.lock(); @@ -1295,10 +1369,11 @@ static bool ta_parse_vdrc(TA_context* ctx) empty_context = false; } - const bool mergeTranslucent = !config::PerStripSorting - || config::RendererType == RenderType::OpenGL_OIT + const bool perPixel = config::RendererType == RenderType::OpenGL_OIT || config::RendererType == RenderType::DirectX11_OIT || config::RendererType == RenderType::Vulkan_OIT; + const bool mergeTranslucent = config::PerStripSorting || perPixel; + TA_context *childCtx = ctx; int pass = 0; while (childCtx != nullptr) @@ -1328,6 +1403,7 @@ static bool ta_parse_vdrc(TA_context* ctx) if (pass == 0 || !empty_pass) { RenderPass *render_pass = vd_rc.render_passes.Append(); + getRegionSettings(pass, *render_pass); render_pass->op_count = vd_rc.global_param_op.used(); make_index(&vd_rc.global_param_op, op_poly_count, render_pass->op_count, true, &vd_rc); @@ -1338,11 +1414,13 @@ static bool ta_parse_vdrc(TA_context* ctx) render_pass->pt_count, true, &vd_rc); pt_poly_count = render_pass->pt_count; render_pass->tr_count = vd_rc.global_param_tr.used(); + if (render_pass->autosort && config::PerStripSorting && !perPixel) + sortPolyParams(&vd_rc.global_param_tr, tr_poly_count, + render_pass->tr_count, &vd_rc); make_index(&vd_rc.global_param_tr, tr_poly_count, render_pass->tr_count, mergeTranslucent, &vd_rc); tr_poly_count = render_pass->tr_count; render_pass->mvo_tr_count = vd_rc.global_param_mvo_tr.used(); - getRegionSettings(pass, *render_pass); } childCtx = childCtx->nextContext; pass++; @@ -1413,14 +1491,16 @@ static bool ta_parse_naomi2(TA_context* ctx) int op_count = 0; int pt_count = 0; int tr_count = 0; - const bool mergeTranslucent = !config::PerStripSorting - || config::RendererType == RenderType::OpenGL_OIT + const bool perPixel = config::RendererType == RenderType::OpenGL_OIT || config::RendererType == RenderType::DirectX11_OIT || config::RendererType == RenderType::Vulkan_OIT; + const bool mergeTranslucent = config::PerStripSorting || perPixel; for (const RenderPass& pass : ctx->rend.render_passes) { make_index(&ctx->rend.global_param_op, op_count, pass.op_count, true, &ctx->rend); make_index(&ctx->rend.global_param_pt, pt_count, pass.pt_count, true, &ctx->rend); + if (pass.autosort && config::PerStripSorting && !perPixel) + sortPolyParams(&ctx->rend.global_param_tr, tr_count, pass.tr_count, &ctx->rend); make_index(&ctx->rend.global_param_tr, tr_count, pass.tr_count, mergeTranslucent, &ctx->rend); op_count = pass.op_count; pt_count = pass.pt_count; diff --git a/core/rend/dx11/dx11_renderer.cpp b/core/rend/dx11/dx11_renderer.cpp index bb9da4990..91215122e 100644 --- a/core/rend/dx11/dx11_renderer.cpp +++ b/core/rend/dx11/dx11_renderer.cpp @@ -882,7 +882,6 @@ void DX11Renderer::drawStrips() } else { - SortPParams(previous_pass.tr_count, tr_count); drawList(pvrrc.global_param_tr, previous_pass.tr_count, tr_count); } } diff --git a/core/rend/dx9/d3d_renderer.cpp b/core/rend/dx9/d3d_renderer.cpp index 070408331..5a3168757 100644 --- a/core/rend/dx9/d3d_renderer.cpp +++ b/core/rend/dx9/d3d_renderer.cpp @@ -775,7 +775,6 @@ void D3DRenderer::drawStrips() } else { - SortPParams(previous_pass.tr_count, tr_count); drawList(pvrrc.global_param_tr, previous_pass.tr_count, tr_count); } } diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 367811ca8..7360910c5 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -688,7 +688,6 @@ void DrawStrips() } else { - 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); } } diff --git a/core/rend/sorter.cpp b/core/rend/sorter.cpp index 29172033c..d5b3e2675 100644 --- a/core/rend/sorter.cpp +++ b/core/rend/sorter.cpp @@ -17,8 +17,6 @@ #include "sorter.h" #include "hw/pvr/Renderer_if.h" #include -#include -#include struct IndexTrig { @@ -37,87 +35,12 @@ static bool operator<(const IndexTrig& left, const IndexTrig& right) return left.z < right.z; } -static bool operator<(const PolyParam& left, const PolyParam& right) -{ - return left.zvZ < right.zvZ; -} - static float getProjectedZ(const Vertex *v, const float *mat) { // -1 / z return -1 / (mat[2] * v->x + mat[1 * 4 + 2] * v->y + mat[2 * 4 + 2] * v->z + mat[3 * 4 + 2]); } -void SortPParams(int first, int count) -{ - if (pvrrc.verts.used() == 0 || count <= 1) - return; - - Vertex* vtx_base=pvrrc.verts.head(); - u32* idx_base = pvrrc.idx.head(); - - PolyParam* pp = &pvrrc.global_param_tr.head()[first]; - PolyParam* pp_end = pp + count; - - while(pp!=pp_end) - { - if (pp->count<2) - { - pp->zvZ=0; - } - else - { - u32* idx = idx_base + pp->first; - - Vertex* vtx=vtx_base+idx[0]; - Vertex* vtx_end=vtx_base + idx[pp->count-1]+1; - - if (pp->isNaomi2()) - { - glm::mat4 mvMat = pp->mvMatrix != nullptr ? glm::make_mat4(pp->mvMatrix) : glm::mat4(1); - glm::vec3 min{ 1e38f, 1e38f, 1e38f }; - glm::vec3 max{ -1e38f, -1e38f, -1e38f }; - while (vtx != vtx_end) - { - glm::vec3 pos{ vtx->x, vtx->y, vtx->z }; - min = glm::min(min, pos); - max = glm::max(max, pos); - vtx++; - } - glm::vec4 center((min + max) / 2.f, 1); - glm::vec4 extents(max - glm::vec3(center), 0); - // transform - center = mvMat * center; - glm::vec3 extentX = mvMat * glm::vec4(extents.x, 0, 0, 0); - glm::vec3 extentY = mvMat * glm::vec4(0, extents.y, 0, 0); - glm::vec3 extentZ = mvMat * glm::vec4(0, 0, extents.z, 0); - // new AA extents - glm::vec3 newExtent = glm::abs(extentX) + glm::abs(extentY) + glm::abs(extentZ); - - min = glm::vec3(center) - newExtent; - max = glm::vec3(center) + newExtent; - - // project - pp->zvZ = -1 / std::min(min.z, max.z); - } - else - { - u32 zv=0xFFFFFFFF; - while(vtx!=vtx_end) - { - zv = std::min(zv, (u32&)vtx->z); - vtx++; - } - - pp->zvZ=(f32&)zv; - } - } - pp++; - } - - std::stable_sort(pvrrc.global_param_tr.head() + first, pvrrc.global_param_tr.head() + first + count); -} - const static Vertex *vtx_sort_base; static void fill_id(u32 *d, const Vertex *v0, const Vertex *v1, const Vertex *v2, const Vertex *vb) diff --git a/core/rend/sorter.h b/core/rend/sorter.h index 92dfdb99b..02b4c76e2 100644 --- a/core/rend/sorter.h +++ b/core/rend/sorter.h @@ -20,9 +20,6 @@ #include -//Sort based on min-z of each strip -void SortPParams(int first, int count); - struct SortTrigDrawParam { const PolyParam* ppid; diff --git a/core/rend/vulkan/drawer.cpp b/core/rend/vulkan/drawer.cpp index a884625e3..735f1aef2 100644 --- a/core/rend/vulkan/drawer.cpp +++ b/core/rend/vulkan/drawer.cpp @@ -303,17 +303,6 @@ bool Drawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) setFirstProvokingVertex(pvrrc); - // Do per-poly sorting - RenderPass previous_pass = {}; - if (config::PerStripSorting) - for (int render_pass = 0; render_pass < pvrrc.render_passes.used(); render_pass++) - { - const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass]; - if (current_pass.autosort) - SortPParams(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count); - previous_pass = current_pass; - } - // Upload vertex and index buffers VertexShaderUniforms vtxUniforms; vtxUniforms.ndcMat = matrices.GetNormalMatrix(); @@ -334,7 +323,7 @@ bool Drawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) std::array pushConstants = { 0, 0, 0, 0, 0 }; cmdBuffer.pushConstants(pipelineManager->GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants); - previous_pass = {}; + RenderPass previous_pass{}; for (int render_pass = 0; render_pass < pvrrc.render_passes.used(); render_pass++) { const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass];