diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index a71ddf4da5..3fc9bd9026 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -79,7 +79,6 @@ enum { DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan, Draw::DrawContext *draw) : vulkan_(vulkan), draw_(draw), - curFrame_(0), stats_{}, vai_(1024) { decOptions_.expandAllWeightsToFloat = false; @@ -279,7 +278,8 @@ void DrawEngineVulkan::DeviceRestore(VulkanContext *vulkan) { void DrawEngineVulkan::BeginFrame() { lastPipeline_ = nullptr; - FrameData *frame = &frame_[curFrame_]; + int curFrame = vulkan_->GetCurFrame(); + FrameData *frame = &frame_[curFrame]; // First reset all buffers, then begin. This is so that Reset can free memory and Begin can allocate it, // if growing the buffer is needed. Doing it this way will reduce fragmentation if more than one buffer @@ -358,16 +358,13 @@ void DrawEngineVulkan::BeginFrame() { } void DrawEngineVulkan::EndFrame() { - FrameData *frame = &frame_[curFrame_]; + FrameData *frame = &frame_[vulkan_->GetCurFrame()]; stats_.pushUBOSpaceUsed = (int)frame->pushUBO->GetOffset(); stats_.pushVertexSpaceUsed = (int)frame->pushVertex->GetOffset(); stats_.pushIndexSpaceUsed = (int)frame->pushIndex->GetOffset(); frame->pushUBO->End(); frame->pushVertex->End(); frame->pushIndex->End(); - curFrame_++; - if (curFrame_ >= vulkan_->GetInflightFrames()) - curFrame_ = 0; vertexCache_->End(); } @@ -520,7 +517,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView assert(light != VK_NULL_HANDLE); assert(bone != VK_NULL_HANDLE); - FrameData *frame = &frame_[curFrame_]; + FrameData *frame = &frame_[vulkan_->GetCurFrame()]; if (!gstate_c.bezier && !gstate_c.spline) { // Has no cache when HW tessellation. VkDescriptorSet d = frame->descSets.Get(key); if (d != VK_NULL_HANDLE) @@ -668,7 +665,7 @@ void DrawEngineVulkan::DoFlush() { // Since we have a new cmdbuf, dirty our dynamic state so it gets re-set. // gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE|DIRTY_DEPTHSTENCIL_STATE|DIRTY_BLEND_STATE); - FrameData *frame = &frame_[curFrame_]; + FrameData *frame = &frame_[vulkan_->GetCurFrame()]; bool textureNeedsApply = false; if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index e1ebba790f..2322dfdc45 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -168,7 +168,7 @@ public: } VulkanPushBuffer *GetPushBufferForTextureData() { - return frame_[curFrame_].pushUBO; + return frame_[vulkan_->GetCurFrame()].pushUBO; } const DrawEngineVulkanStats &GetStats() const { @@ -233,7 +233,6 @@ private: }; GEPrimitiveType lastPrim_ = GE_PRIM_INVALID; - int curFrame_; FrameData frame_[VulkanContext::MAX_INFLIGHT_FRAMES]; // Other diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 3cb01856d1..7b122bfce0 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -218,16 +218,16 @@ void GPU_Vulkan::BeginHostFrame() { textureCacheVulkan_->StartFrame(); - - FrameData &frame = frameData_[curFrame_]; + int curFrame = vulkan_->GetCurFrame(); + FrameData &frame = frameData_[curFrame]; frame.push_->Reset(); frame.push_->Begin(vulkan_); framebufferManagerVulkan_->BeginFrameVulkan(); - framebufferManagerVulkan_->SetPushBuffer(frameData_[curFrame_].push_); - depalShaderCache_.SetPushBuffer(frameData_[curFrame_].push_); - textureCacheVulkan_->SetPushBuffer(frameData_[curFrame_].push_); + framebufferManagerVulkan_->SetPushBuffer(frameData_[curFrame].push_); + depalShaderCache_.SetPushBuffer(frameData_[curFrame].push_); + textureCacheVulkan_->SetPushBuffer(frameData_[curFrame].push_); vulkan2D_.BeginFrame(); @@ -244,16 +244,12 @@ void GPU_Vulkan::BeginHostFrame() { } void GPU_Vulkan::EndHostFrame() { - FrameData &frame = frameData_[curFrame_]; + int curFrame = vulkan_->GetCurFrame(); + FrameData &frame = frameData_[curFrame]; frame.push_->End(); vulkan2D_.EndFrame(); - curFrame_++; - if (curFrame_ >= vulkan_->GetInflightFrames()) { - curFrame_ = 0; - } - drawEngine_.EndFrame(); framebufferManagerVulkan_->EndFrame(); textureCacheVulkan_->EndFrame(); diff --git a/GPU/Vulkan/GPU_Vulkan.h b/GPU/Vulkan/GPU_Vulkan.h index ccdf36b3a4..4c1d49a470 100644 --- a/GPU/Vulkan/GPU_Vulkan.h +++ b/GPU/Vulkan/GPU_Vulkan.h @@ -134,5 +134,4 @@ private: }; FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES]{}; - int curFrame_ = 0; }; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 5fc95714ce..6e6feeb05f 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -550,6 +550,11 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry, bool replaceIm int h = gstate.getTextureHeight(0); ReplacedTexture &replaced = replacer_.FindReplacement(cachekey, entry->fullhash, w, h); if (replaced.GetSize(0, w, h)) { + if (replaceImages) { + // Since we're replacing the texture, we can't replace the image inside. + ReleaseTexture(entry, true); + replaceImages = false; + } // We're replacing, so we won't scale. scaleFactor = 1; entry->status |= TexCacheEntry::STATUS_IS_SCALED; @@ -586,7 +591,9 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry, bool replaceIm if (replaced.Valid()) { actualFmt = ToVulkanFormat(replaced.Format(0)); } - if (!entry->vkTex) { + + if (!entry->vkTex) { // Change to "if (true) {" to always recreate. + delete entry->vkTex; entry->vkTex = new CachedTextureVulkan(); entry->vkTex->texture_ = new VulkanTexture(vulkan_, allocator_); VulkanTexture *image = entry->vkTex->texture_; diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index af0240f736..f07f6b68c7 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -20,7 +20,7 @@ #include "Common/Vulkan/VulkanContext.h" #include "GPU/Vulkan/VulkanUtil.h" -Vulkan2D::Vulkan2D(VulkanContext *vulkan) : vulkan_(vulkan), curFrame_(0) { +Vulkan2D::Vulkan2D(VulkanContext *vulkan) : vulkan_(vulkan) { InitDeviceObjects(); } @@ -121,15 +121,13 @@ void Vulkan2D::DeviceRestore(VulkanContext *vulkan) { } void Vulkan2D::BeginFrame() { - FrameData &frame = frameData_[curFrame_]; + int curFrame = vulkan_->GetCurFrame(); + FrameData &frame = frameData_[curFrame]; frame.descSets.clear(); vkResetDescriptorPool(vulkan_->GetDevice(), frame.descPool, 0); } void Vulkan2D::EndFrame() { - curFrame_++; - if (curFrame_ >= vulkan_->GetInflightFrames()) - curFrame_ = 0; } VkDescriptorSet Vulkan2D::GetDescriptorSet(VkImageView tex1, VkSampler sampler1, VkImageView tex2, VkSampler sampler2) { @@ -139,7 +137,8 @@ VkDescriptorSet Vulkan2D::GetDescriptorSet(VkImageView tex1, VkSampler sampler1, key.sampler[0] = sampler1; key.sampler[1] = sampler2; - FrameData *frame = &frameData_[curFrame_]; + int curFrame = vulkan_->GetCurFrame(); + FrameData *frame = &frameData_[curFrame]; auto iter = frame->descSets.find(key); if (iter != frame->descSets.end()) { return iter->second; diff --git a/GPU/Vulkan/VulkanUtil.h b/GPU/Vulkan/VulkanUtil.h index e9696a7a9c..28bc023109 100644 --- a/GPU/Vulkan/VulkanUtil.h +++ b/GPU/Vulkan/VulkanUtil.h @@ -104,7 +104,6 @@ private: }; FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES]; - int curFrame_ = 0; std::map pipelines_; }; diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 8a7b4ccafd..1223fd8e33 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -536,7 +536,6 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step } renderPass = renderPasses_[RPIndex(step.render.color, step.render.depthStencil)]; - // VLOG("Switching framebuffer to FBO (fc=%d, cmd=%x, rp=%x)", frameNum_, (int)(uintptr_t)cmd_, (int)(uintptr_t)renderPass); if (step.render.color == VKRRenderPassAction::CLEAR) { Uint8x4ToFloat4(clearVal[0].color.float32, step.render.clearColor); numClearVals = 1; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 58ed64bbc1..e3b0fa7745 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -587,15 +587,13 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { VkResult res = vkEndCommandBuffer(frameData.mainCmd); assert(res == VK_SUCCESS); + VkCommandBuffer cmdBufs[2]; int numCmdBufs = 0; - std::vector cmdBufs; - cmdBufs.reserve(2); if (frameData.hasInitCommands) { - cmdBufs.push_back(frameData.initCmd); + cmdBufs[numCmdBufs++] = frameData.initCmd; frameData.hasInitCommands = false; } - - cmdBufs.push_back(frameData.mainCmd); + cmdBufs[numCmdBufs++] = frameData.mainCmd; VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; if (triggerFence) { @@ -605,13 +603,14 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { VkPipelineStageFlags waitStage[1]{ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT }; submit_info.pWaitDstStageMask = waitStage; - submit_info.commandBufferCount = (uint32_t)cmdBufs.size(); - submit_info.pCommandBuffers = cmdBufs.data(); + submit_info.commandBufferCount = (uint32_t)numCmdBufs; + submit_info.pCommandBuffers = cmdBufs; if (triggerFence) { submit_info.signalSemaphoreCount = 1; submit_info.pSignalSemaphores = &renderingCompleteSemaphore_; } res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFence ? frameData.fence : VK_NULL_HANDLE); + if (res == VK_ERROR_DEVICE_LOST) { // _assert_msg_(G3D, false, "Lost the Vulkan device! What did we do wrong?"); ELOG("DEVICE LOST"); diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 06d87cfb1e..acd271deec 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -509,7 +509,6 @@ private: FrameData frame_[VulkanContext::MAX_INFLIGHT_FRAMES]{}; - int frameNum_ = 0; VulkanPushBuffer *push_ = nullptr; DeviceCaps caps_{}; @@ -655,7 +654,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, const TextureDesc &desc) { } VKContext::VKContext(VulkanContext *vulkan) - : vulkan_(vulkan), frameNum_(0), caps_{}, renderManager_(vulkan) { + : vulkan_(vulkan), caps_{}, renderManager_(vulkan) { caps_.anisoSupported = vulkan->GetFeaturesAvailable().samplerAnisotropy != 0; caps_.geometryShaderSupported = vulkan->GetFeaturesAvailable().geometryShader != 0; caps_.tesselationShaderSupported = vulkan->GetFeaturesAvailable().tessellationShader != 0; @@ -742,7 +741,7 @@ VKContext::~VKContext() { void VKContext::BeginFrame() { renderManager_.BeginFrame(); - FrameData &frame = frame_[frameNum_]; + FrameData &frame = frame_[vulkan_->GetCurFrame()]; push_ = frame.pushBuffer; // OK, we now know that nothing is reading from this frame's data pushbuffer, @@ -764,16 +763,13 @@ void VKContext::EndFrame() { renderManager_.Finish(); - frameNum_++; - if (frameNum_ >= vulkan_->GetInflightFrames()) - frameNum_ = 0; push_ = nullptr; } VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { DescriptorSetKey key; - FrameData *frame = &frame_[frameNum_]; + FrameData *frame = &frame_[vulkan_->GetCurFrame()]; key.texture_ = boundTextures_[0]; key.sampler_ = boundSamplers_[0];