From 47f262a2c6e3753ef0718f2cd34088d944bfff7a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 19 Nov 2020 22:29:06 +0100 Subject: [PATCH] vk: use normal pipeline for raw fb display raw fb also needs to be rotated/scaled oit: draw opaque polys on first frame --- core/hw/pvr/Renderer_if.cpp | 30 ++++++---- core/hw/pvr/ta_ctx.cpp | 32 ----------- core/hw/pvr/ta_ctx.h | 2 - core/hw/pvr/ta_vtx.cpp | 3 +- core/rend/gles/gles.cpp | 3 - core/rend/vulkan/drawer.cpp | 70 ++++++++++------------- core/rend/vulkan/oit/oit_drawer.cpp | 13 +++++ core/rend/vulkan/oit/oit_renderer.cpp | 3 - core/rend/vulkan/vulkan_renderer.cpp | 3 - core/rend/vulkan/vulkan_renderer.h | 82 ++++++++++++++++++++++----- 10 files changed, 134 insertions(+), 107 deletions(-) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index e0f3d4170..0fec28914 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -394,20 +394,29 @@ void rend_start_render() if (ctx) { - bool is_rtt=(FB_W_SOF1& 0x1000000)!=0 && !ctx->rend.isRenderFramebuffer; - - //tactx_Recycle(ctx); ctx = read_frame("frames/dcframe-SoA-intro-tr-autosort"); - //printf("REP: %.2f ms\n",render_end_pending_cycles/200000.0); - if (!ctx->rend.isRenderFramebuffer) + if (ctx->rend.isRenderFramebuffer) + { + ctx->rend.isRTT = false; + ctx->rend.fb_X_CLIP.min = 0; + ctx->rend.fb_X_CLIP.max = 639; + ctx->rend.fb_Y_CLIP.min = 0; + ctx->rend.fb_Y_CLIP.max = 479; + + ctx->rend.fog_clamp_min = 0; + ctx->rend.fog_clamp_max = 0xffffffff; + } + else + { FillBGP(ctx); - ctx->rend.isRTT=is_rtt; + ctx->rend.isRTT = (FB_W_SOF1 & 0x1000000) != 0; - ctx->rend.fb_X_CLIP=FB_X_CLIP; - ctx->rend.fb_Y_CLIP=FB_Y_CLIP; + ctx->rend.fb_X_CLIP = FB_X_CLIP; + ctx->rend.fb_Y_CLIP = FB_Y_CLIP; - ctx->rend.fog_clamp_min = FOG_CLAMP_MIN; - ctx->rend.fog_clamp_max = FOG_CLAMP_MAX; + ctx->rend.fog_clamp_min = FOG_CLAMP_MIN; + ctx->rend.fog_clamp_max = FOG_CLAMP_MAX; + } if (QueueRender(ctx)) { @@ -460,7 +469,6 @@ void rend_vblank() SetCurrentTARC(CORE_CURRENT_CTX); ta_ctx->Reset(); ta_ctx->rend.isRenderFramebuffer = true; - ta_ctx->rend.isRTT = false; rend_start_render(); PARAM_BASE = saved_ctx_addr; if (restore_ctx) diff --git a/core/hw/pvr/ta_ctx.cpp b/core/hw/pvr/ta_ctx.cpp index 2ad2a7c64..2288c689f 100644 --- a/core/hw/pvr/ta_ctx.cpp +++ b/core/hw/pvr/ta_ctx.cpp @@ -66,38 +66,6 @@ void SetCurrentTARC(u32 addr) } } -bool TryDecodeTARC() -{ - verify(ta_ctx != 0); - - if (vd_ctx == 0) - { - vd_ctx = ta_ctx; - - vd_ctx->rend.proc_start = vd_ctx->rend.proc_end + 32; - vd_ctx->rend.proc_end = vd_ctx->tad.thd_data; - - vd_ctx->rend_inuse.lock(); - vd_rc = vd_ctx->rend; - - //signal the vdec thread - return true; - } - else - return false; -} - -void VDecEnd() -{ - verify(vd_ctx != 0); - - vd_ctx->rend = vd_rc; - - vd_ctx->rend_inuse.unlock(); - - vd_ctx = 0; -} - static std::mutex mtx_rqueue; TA_context* rqueue; cResetEvent frame_finished; diff --git a/core/hw/pvr/ta_ctx.h b/core/hw/pvr/ta_ctx.h index 6e54b5709..6b639f53b 100644 --- a/core/hw/pvr/ta_ctx.h +++ b/core/hw/pvr/ta_ctx.h @@ -268,8 +268,6 @@ void SetCurrentTARC(u32 addr); bool QueueRender(TA_context* ctx); TA_context* DequeueRender(); void FinishRender(TA_context* ctx); -bool TryDecodeTARC(); -void VDecEnd(); //must be moved to proper header void FillBGP(TA_context* ctx); diff --git a/core/hw/pvr/ta_vtx.cpp b/core/hw/pvr/ta_vtx.cpp index 5196cb93a..b063998e5 100644 --- a/core/hw/pvr/ta_vtx.cpp +++ b/core/hw/pvr/ta_vtx.cpp @@ -1574,11 +1574,12 @@ static void fix_texture_bleeding(const List *list) bool ta_parse_vdrc(TA_context* ctx) { + ctx->rend_inuse.lock(); bool rv=false; verify(vd_ctx == 0); vd_ctx = ctx; vd_rc = vd_ctx->rend; - + ta_parse_cnt++; if (ctx->rend.isRTT || 0 == (ta_parse_cnt % ( settings.pvr.ta_skip + 1))) { diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index bef25a216..f98f45722 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1045,15 +1045,12 @@ void OSD_DRAW(bool clear_screen) bool ProcessFrame(TA_context* ctx) { - ctx->rend_inuse.lock(); - if (KillTex) TexCache.Clear(); if (ctx->rend.isRenderFramebuffer) { RenderFramebuffer(); - ctx->rend_inuse.unlock(); } else { diff --git a/core/rend/vulkan/drawer.cpp b/core/rend/vulkan/drawer.cpp index a3531e917..3791be0be 100644 --- a/core/rend/vulkan/drawer.cpp +++ b/core/rend/vulkan/drawer.cpp @@ -63,44 +63,36 @@ void BaseDrawer::SetBaseScissor() && !matrices.IsClipped() && !settings.rend.Rotate90; if (!wide_screen_on) { - if (pvrrc.isRenderFramebuffer) - { - baseScissor = vk::Rect2D(vk::Offset2D(0, 0), - vk::Extent2D(640, 480)); - } - else - { - float width; - float height; - float min_x; - float min_y; - glm::vec4 clip_min(pvrrc.fb_X_CLIP.min, pvrrc.fb_Y_CLIP.min, 0, 1); - glm::vec4 clip_dim(pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1, - pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1, 0, 0); - clip_min = matrices.GetScissorMatrix() * clip_min; - clip_dim = matrices.GetScissorMatrix() * clip_dim; + float width; + float height; + float min_x; + float min_y; + glm::vec4 clip_min(pvrrc.fb_X_CLIP.min, pvrrc.fb_Y_CLIP.min, 0, 1); + glm::vec4 clip_dim(pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1, + pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1, 0, 0); + clip_min = matrices.GetScissorMatrix() * clip_min; + clip_dim = matrices.GetScissorMatrix() * clip_dim; - min_x = clip_min[0]; - min_y = clip_min[1]; - width = clip_dim[0]; - height = clip_dim[1]; - if (width < 0) - { - min_x += width; - width = -width; - } - if (height < 0) - { - min_y += height; - height = -height; - } - - baseScissor = vk::Rect2D( - vk::Offset2D((u32) std::max(lroundf(min_x), 0L), - (u32) std::max(lroundf(min_y), 0L)), - vk::Extent2D((u32) std::max(lroundf(width), 0L), - (u32) std::max(lroundf(height), 0L))); + min_x = clip_min[0]; + min_y = clip_min[1]; + width = clip_dim[0]; + height = clip_dim[1]; + if (width < 0) + { + min_x += width; + width = -width; } + if (height < 0) + { + min_y += height; + height = -height; + } + + baseScissor = vk::Rect2D( + vk::Offset2D((u32) std::max(lroundf(min_x), 0L), + (u32) std::max(lroundf(min_y), 0L)), + vk::Extent2D((u32) std::max(lroundf(width), 0L), + (u32) std::max(lroundf(height), 0L))); } else { @@ -316,9 +308,6 @@ void Drawer::UploadMainBuffer(const VertexShaderUniforms& vertexUniforms, const bool Drawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) { - VertexShaderUniforms vtxUniforms; - vtxUniforms.normal_matrix = matrices.GetNormalMatrix(); - FragmentShaderUniforms fragUniforms = MakeFragmentUniforms(); SortTriangles(); @@ -329,6 +318,9 @@ bool Drawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) SetProvokingVertices(); // Upload vertex and index buffers + VertexShaderUniforms vtxUniforms; + vtxUniforms.normal_matrix = matrices.GetNormalMatrix(); + UploadMainBuffer(vtxUniforms, fragUniforms); // Update per-frame descriptor set and bind it diff --git a/core/rend/vulkan/oit/oit_drawer.cpp b/core/rend/vulkan/oit/oit_drawer.cpp index 4b648870a..76fc9b65c 100644 --- a/core/rend/vulkan/oit/oit_drawer.cpp +++ b/core/rend/vulkan/oit/oit_drawer.cpp @@ -377,8 +377,21 @@ bool OITDrawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) vk::DependencyFlagBits::eByRegion, 1, &memoryBarrier, 0, nullptr, 0, nullptr); vk::Pipeline pipeline = pipelineManager->GetClearPipeline(); cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); + quadBuffer->Bind(cmdBuffer); quadBuffer->Draw(cmdBuffer); + if (oitBuffers->isFirstFrameAfterInit()) + { + // missing the transparent stuff on the first frame cuz I'm lazy + vk::MemoryBarrier memoryBarrier(vk::AccessFlagBits::eShaderWrite, vk::AccessFlagBits::eShaderRead); + cmdBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader, vk::PipelineStageFlagBits::eFragmentShader, + vk::DependencyFlagBits::eByRegion, 1, &memoryBarrier, 0, nullptr, 0, nullptr); + pipeline = pipelineManager->GetFinalPipeline(); + cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); + quadBuffer->Bind(cmdBuffer); + quadBuffer->Draw(cmdBuffer); + } + if (!finalPass) { // Re-bind vertex and index buffers diff --git a/core/rend/vulkan/oit/oit_renderer.cpp b/core/rend/vulkan/oit/oit_renderer.cpp index fb2745f52..c0d16b2dd 100644 --- a/core/rend/vulkan/oit/oit_renderer.cpp +++ b/core/rend/vulkan/oit/oit_renderer.cpp @@ -68,9 +68,6 @@ public: bool Render() override { - if (pvrrc.isRenderFramebuffer) - return true; - OITDrawer *drawer; if (pvrrc.isRTT) drawer = &textureDrawer; diff --git a/core/rend/vulkan/vulkan_renderer.cpp b/core/rend/vulkan/vulkan_renderer.cpp index 8cb10662b..06cef241e 100644 --- a/core/rend/vulkan/vulkan_renderer.cpp +++ b/core/rend/vulkan/vulkan_renderer.cpp @@ -55,9 +55,6 @@ public: bool Render() override { - if (pvrrc.isRenderFramebuffer) - return true; - Drawer *drawer; if (pvrrc.isRTT) drawer = &textureDrawer; diff --git a/core/rend/vulkan/vulkan_renderer.h b/core/rend/vulkan/vulkan_renderer.h index 413573835..00189d8a0 100644 --- a/core/rend/vulkan/vulkan_renderer.h +++ b/core/rend/vulkan/vulkan_renderer.h @@ -108,21 +108,20 @@ public: virtual bool Process(TA_context* ctx) override { - texCommandPool.BeginFrame(); - textureCache.SetCurrentIndex(texCommandPool.GetIndex()); - - if (ctx->rend.isRenderFramebuffer) - return RenderFramebuffer(); - - ctx->rend_inuse.lock(); - if (KillTex) textureCache.Clear(); - bool result = ta_parse_vdrc(ctx); - + texCommandPool.BeginFrame(); + textureCache.SetCurrentIndex(texCommandPool.GetIndex()); textureCache.CollectCleanup(); + bool result; + + if (ctx->rend.isRenderFramebuffer) + result = RenderFramebuffer(ctx); + else + result = ta_parse_vdrc(ctx); + if (result) { CheckFogTexture(); @@ -191,7 +190,7 @@ public: protected: VulkanContext *GetContext() const { return VulkanContext::Instance(); } - bool RenderFramebuffer() + bool RenderFramebuffer(TA_context* ctx) { if (FB_R_SIZE.fb_x_size == 0 || FB_R_SIZE.fb_y_size == 0) return false; @@ -216,9 +215,66 @@ protected: curTexture->SetCommandBuffer(texCommandPool.Allocate()); curTexture->UploadToGPU(width, height, (u8*)pb.data(), false); curTexture->SetCommandBuffer(nullptr); - texCommandPool.EndFrame(); - GetContext()->PresentFrame(curTexture->GetImageView(), { 640, 480 }); + Vertex *vtx = ctx->rend.verts.Append(4); + vtx[0].x = 0.f; + vtx[0].y = 0.f; + vtx[0].z = 0.1f; + vtx[0].u = 0.f; + vtx[0].v = 0.f; + + vtx[1] = vtx[0]; + vtx[1].x = 640.f; + vtx[1].u = 1.f; + + vtx[2] = vtx[0]; + vtx[2].y = 480.f; + vtx[2].v = 1.f; + + vtx[3] = vtx[0]; + vtx[3].x = 640.f; + vtx[3].y = 480.f; + vtx[3].u = 1.f; + vtx[3].v = 1.f; + + u32 *idx = ctx->rend.idx.Append(4); + idx[0] = ctx->rend.verts.used() - 4; + idx[1] = idx[0] + 1; + idx[2] = idx[1] + 1; + idx[3] = idx[2] + 1; + + PolyParam *pp = ctx->rend.global_param_op.Append(1); + pp->first = ctx->rend.idx.used() - 4; + pp->count = 4; + + pp->isp.full = 0; + pp->isp.DepthMode = 7; + + pp->pcw.full = 0; + pp->pcw.Gouraud = 1; + pp->pcw.Texture = 1; + + pp->tcw.full = 0; + pp->tcw.TexAddr = 0x1fffff; + pp->tcw1.full = (u32)-1; + + pp->tsp.full = 0; + pp->tsp.FilterMode = 1; + pp->tsp.FogCtrl = 2; + pp->tsp.SrcInstr = 1; + pp->tsp1.full = (u32)-1; + + pp->texid = (u64)reinterpret_cast(curTexture.get()); + pp->texid1 = (u64)-1; + pp->tileclip = 0; + + RenderPass *pass = ctx->rend.render_passes.Append(1); + pass->autosort = false; + pass->mvo_count = 0; + pass->mvo_tr_count = 0; + pass->op_count = ctx->rend.global_param_op.used(); + pass->pt_count = 0; + pass->tr_count = 0; return true; }