From b6e00cb208cc3961afea7998908fda91e8bd7179 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 27 May 2019 21:23:58 +0200 Subject: [PATCH] - fix use after delete of some textures --- .../polyrenderer/backend/poly_framebuffer.cpp | 1 + .../polyrenderer/backend/poly_framebuffer.h | 1 + .../polyrenderer/backend/poly_hwtexture.cpp | 22 ++++++++++++++----- .../polyrenderer/backend/poly_hwtexture.h | 1 + .../polyrenderer/backend/poly_renderstate.cpp | 21 +++++++++--------- .../polyrenderer/backend/poly_renderstate.h | 1 + 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/rendering/polyrenderer/backend/poly_framebuffer.cpp b/src/rendering/polyrenderer/backend/poly_framebuffer.cpp index d457aea49..b6397b859 100644 --- a/src/rendering/polyrenderer/backend/poly_framebuffer.cpp +++ b/src/rendering/polyrenderer/backend/poly_framebuffer.cpp @@ -140,6 +140,7 @@ void PolyFrameBuffer::Update() DrawerThreads::WaitForWorkers(); mFrameMemory.Clear(); FrameDeleteList.Buffers.clear(); + FrameDeleteList.Images.clear(); if (mCanvas) { diff --git a/src/rendering/polyrenderer/backend/poly_framebuffer.h b/src/rendering/polyrenderer/backend/poly_framebuffer.h index e56318145..e6f6e2afd 100644 --- a/src/rendering/polyrenderer/backend/poly_framebuffer.h +++ b/src/rendering/polyrenderer/backend/poly_framebuffer.h @@ -62,6 +62,7 @@ public: struct DeleteList { std::vector> Buffers; + std::vector> Images; } FrameDeleteList; private: diff --git a/src/rendering/polyrenderer/backend/poly_hwtexture.cpp b/src/rendering/polyrenderer/backend/poly_hwtexture.cpp index 9302738be..ff3ee95fa 100644 --- a/src/rendering/polyrenderer/backend/poly_hwtexture.cpp +++ b/src/rendering/polyrenderer/backend/poly_hwtexture.cpp @@ -34,11 +34,15 @@ void PolyHardwareTexture::ResetAll() void PolyHardwareTexture::Reset() { + if (auto fb = GetPolyFrameBuffer()) + { + auto &deleteList = fb->FrameDeleteList; + if (mCanvas) deleteList.Images.push_back(std::move(mCanvas)); + } } void PolyHardwareTexture::Precache(FMaterial *mat, int translation, int flags) { -#if 0 int numLayers = mat->GetLayers(); GetImage(mat->tex, translation, flags); for (int i = 1; i < numLayers; i++) @@ -47,15 +51,16 @@ void PolyHardwareTexture::Precache(FMaterial *mat, int translation, int flags) auto systex = static_cast(mat->GetLayer(i, 0, &layer)); systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0); } -#endif } DCanvas *PolyHardwareTexture::GetImage(const FMaterialState &state) { + FTexture *tex = state.mMaterial->tex; + if (tex->isHardwareCanvas()) static_cast(tex)->NeedUpdate(); + if (!mCanvas) { FMaterial *mat = state.mMaterial; - FTexture *tex = state.mMaterial->tex; int clampmode = state.mClampMode; int translation = state.mTranslation; @@ -66,14 +71,19 @@ DCanvas *PolyHardwareTexture::GetImage(const FMaterialState &state) // Textures that are already scaled in the texture lump will not get replaced by hires textures. int flags = state.mMaterial->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0; - if (tex->isHardwareCanvas()) static_cast(tex)->NeedUpdate(); - - CreateImage(tex, translation, flags); + return GetImage(tex, translation, flags); } return mCanvas.get(); } +DCanvas *PolyHardwareTexture::GetImage(FTexture *tex, int translation, int flags) +{ + if (!mCanvas) + CreateImage(tex, translation, flags); + return mCanvas.get(); +} + void PolyHardwareTexture::AllocateBuffer(int w, int h, int texelsize) { if (!mCanvas || mCanvas->GetWidth() != w || mCanvas->GetHeight() != h) diff --git a/src/rendering/polyrenderer/backend/poly_hwtexture.h b/src/rendering/polyrenderer/backend/poly_hwtexture.h index 84d1147bf..805fd37da 100644 --- a/src/rendering/polyrenderer/backend/poly_hwtexture.h +++ b/src/rendering/polyrenderer/backend/poly_hwtexture.h @@ -26,6 +26,7 @@ public: void Precache(FMaterial *mat, int translation, int flags); DCanvas *GetImage(const FMaterialState &state); + DCanvas *GetImage(FTexture *tex, int translation, int flags); // Software renderer stuff void AllocateBuffer(int w, int h, int texelsize) override; diff --git a/src/rendering/polyrenderer/backend/poly_renderstate.cpp b/src/rendering/polyrenderer/backend/poly_renderstate.cpp index cece607d1..5e770c1db 100644 --- a/src/rendering/polyrenderer/backend/poly_renderstate.cpp +++ b/src/rendering/polyrenderer/backend/poly_renderstate.cpp @@ -166,8 +166,6 @@ void PolyRenderState::Apply() drawcalls.Clock(); auto fb = GetPolyFrameBuffer(); - PolyPushConstants constants; - int fogset = 0; if (mFogEnabled) { @@ -185,12 +183,16 @@ void PolyRenderState::Apply() } } - int tempTM = TM_NORMAL; - if (mMaterial.mMaterial && mMaterial.mMaterial->tex && mMaterial.mMaterial->tex->isHardwareCanvas()) - tempTM = TM_OPAQUE; + ApplyMaterial(); + if (mVertexBuffer) PolyTriangleDrawer::SetVertexBuffer(fb->GetDrawCommands(), mVertexBuffer->Memory()); + if (mIndexBuffer) PolyTriangleDrawer::SetIndexBuffer(fb->GetDrawCommands(), mIndexBuffer->Memory()); + PolyTriangleDrawer::SetInputAssembly(fb->GetDrawCommands(), static_cast(mVertexBuffer)->VertexFormat); + PolyTriangleDrawer::SetRenderStyle(fb->GetDrawCommands(), mRenderStyle); + + PolyPushConstants constants; constants.uFogEnabled = fogset; - constants.uTextureMode = mTextureMode == TM_NORMAL && tempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode; + constants.uTextureMode = mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode; constants.uLightDist = mLightParms[0]; constants.uLightFactor = mLightParms[1]; constants.uFogDensity = mLightParms[2]; @@ -199,13 +201,8 @@ void PolyRenderState::Apply() constants.uClipSplit = { mClipSplit[0], mClipSplit[1] }; constants.uLightIndex = mLightIndex; - if (mVertexBuffer) PolyTriangleDrawer::SetVertexBuffer(fb->GetDrawCommands(), mVertexBuffer->Memory()); - if (mIndexBuffer) PolyTriangleDrawer::SetIndexBuffer(fb->GetDrawCommands(), mIndexBuffer->Memory()); - PolyTriangleDrawer::SetInputAssembly(fb->GetDrawCommands(), static_cast(mVertexBuffer)->VertexFormat); - PolyTriangleDrawer::SetRenderStyle(fb->GetDrawCommands(), mRenderStyle); PolyTriangleDrawer::PushStreamData(fb->GetDrawCommands(), mStreamData, constants); ApplyMatrices(); - ApplyMaterial(); if (mBias.mChanged) { @@ -220,6 +217,8 @@ void PolyRenderState::ApplyMaterial() { if (mMaterial.mChanged && mMaterial.mMaterial) { + mTempTM = mMaterial.mMaterial->tex->isHardwareCanvas() ? TM_OPAQUE : TM_NORMAL; + auto base = static_cast(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation)); if (base) { diff --git a/src/rendering/polyrenderer/backend/poly_renderstate.h b/src/rendering/polyrenderer/backend/poly_renderstate.h index b0fee75ce..8634d64e5 100644 --- a/src/rendering/polyrenderer/backend/poly_renderstate.h +++ b/src/rendering/polyrenderer/backend/poly_renderstate.h @@ -62,4 +62,5 @@ private: std::vector> mVertexFormats; bool mDepthClamp = true; + int mTempTM = TM_NORMAL; };