From 8a5f07b860d6472de8b9be40873f270a1698bf24 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Nov 2021 15:25:28 -0800 Subject: [PATCH] Vulkan: Don't cache vulkan_ with draw context. Since we can get the VulkanContext cheaply from the draw context, it's easier to make sure things stay up to date. --- GPU/Vulkan/DepalettizeShaderVulkan.cpp | 24 ++++---- GPU/Vulkan/DepalettizeShaderVulkan.h | 5 +- GPU/Vulkan/DrawEngineVulkan.cpp | 80 ++++++++++++++----------- GPU/Vulkan/DrawEngineVulkan.h | 10 ++-- GPU/Vulkan/FramebufferManagerVulkan.cpp | 32 +++++----- GPU/Vulkan/FramebufferManagerVulkan.h | 4 +- GPU/Vulkan/GPU_Vulkan.cpp | 60 ++++++++++--------- GPU/Vulkan/GPU_Vulkan.h | 1 - GPU/Vulkan/ShaderManagerVulkan.cpp | 27 +++++---- GPU/Vulkan/ShaderManagerVulkan.h | 5 +- GPU/Vulkan/StencilBufferVulkan.cpp | 8 ++- GPU/Vulkan/TextureCacheVulkan.cpp | 37 ++++++------ GPU/Vulkan/TextureCacheVulkan.h | 4 +- 13 files changed, 158 insertions(+), 139 deletions(-) diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.cpp b/GPU/Vulkan/DepalettizeShaderVulkan.cpp index e5d6cf2d0a..7707853bb9 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.cpp +++ b/GPU/Vulkan/DepalettizeShaderVulkan.cpp @@ -57,9 +57,9 @@ static VkFormat GetClutDestFormat(GEPaletteFormat format, VkComponentMapping *co return VK_FORMAT_UNDEFINED; } -DepalShaderCacheVulkan::DepalShaderCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan) - : draw_(draw), vulkan_(vulkan) { - DeviceRestore(draw, vulkan); +DepalShaderCacheVulkan::DepalShaderCacheVulkan(Draw::DrawContext *draw) + : draw_(draw) { + DeviceRestore(draw); } DepalShaderCacheVulkan::~DepalShaderCacheVulkan() { @@ -69,19 +69,19 @@ DepalShaderCacheVulkan::~DepalShaderCacheVulkan() { void DepalShaderCacheVulkan::DeviceLost() { Clear(); if (vshader_) { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); vulkan2D_->PurgeVertexShader(vshader_); - vulkan_->Delete().QueueDeleteShaderModule(vshader_); + vulkan->Delete().QueueDeleteShaderModule(vshader_); vshader_ = VK_NULL_HANDLE; } draw_ = nullptr; - vulkan_ = nullptr; } -void DepalShaderCacheVulkan::DeviceRestore(Draw::DrawContext *draw, VulkanContext *vulkan) { +void DepalShaderCacheVulkan::DeviceRestore(Draw::DrawContext *draw) { draw_ = draw; - vulkan_ = vulkan; std::string errors; - vshader_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, depal_vs, &errors); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + vshader_ = CompileShaderModule(vulkan, VK_SHADER_STAGE_VERTEX_BIT, depal_vs, &errors); _assert_(vshader_ != VK_NULL_HANDLE); } @@ -94,12 +94,13 @@ DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMod } VkRenderPass rp = (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::FRAMEBUFFER_RENDERPASS); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); char *buffer = new char[2048]; GenerateDepalShader(buffer, pixelFormat, GLSL_VULKAN); std::string error; - VkShaderModule fshader = CompileShaderModule(vulkan_, VK_SHADER_STAGE_FRAGMENT_BIT, buffer, &error); + VkShaderModule fshader = CompileShaderModule(vulkan, VK_SHADER_STAGE_FRAGMENT_BIT, buffer, &error); if (fshader == VK_NULL_HANDLE) { INFO_LOG(G3D, "Source:\n%s\n\n", buffer); Crash(); @@ -112,7 +113,7 @@ DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMod // Maybe don't even need to queue it.. // "true" keeps the pipeline itself alive, forgetting the fshader. vulkan2D_->PurgeFragmentShader(fshader, true); - vulkan_->Delete().QueueDeleteShaderModule(fshader); + vulkan->Delete().QueueDeleteShaderModule(fshader); DepalShaderVulkan *depal = new DepalShaderVulkan(); depal->pipeline = pipeline; @@ -130,6 +131,7 @@ VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat return oldtex->second->texture; } + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); VkComponentMapping componentMapping; VkFormat destFormat = GetClutDestFormat(clutFormat, &componentMapping); @@ -163,7 +165,7 @@ VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat dstFmt = GetClutDestFormat(clutFormat, &componentMapping); } - VulkanTexture *vktex = new VulkanTexture(vulkan_); + VulkanTexture *vktex = new VulkanTexture(vulkan); vktex->SetTag("DepalClut"); VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); if (!vktex->CreateDirect(cmd, alloc_, texturePixels, 1, 1, destFormat, diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.h b/GPU/Vulkan/DepalettizeShaderVulkan.h index e78d817feb..87be7c0d6f 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.h +++ b/GPU/Vulkan/DepalettizeShaderVulkan.h @@ -48,10 +48,10 @@ class VulkanPushBuffer; // Could even avoid bothering with palette texture and just use uniform data... class DepalShaderCacheVulkan : public DepalShaderCacheCommon { public: - DepalShaderCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan); + DepalShaderCacheVulkan(Draw::DrawContext *draw); ~DepalShaderCacheVulkan(); void DeviceLost(); - void DeviceRestore(Draw::DrawContext *draw, VulkanContext *vulkan); + void DeviceRestore(Draw::DrawContext *draw); // This also uploads the palette and binds the correct texture. DepalShaderVulkan *GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat); @@ -66,7 +66,6 @@ public: private: Draw::DrawContext *draw_ = nullptr; - VulkanContext *vulkan_ = nullptr; VulkanPushBuffer *push_ = nullptr; VulkanDeviceAllocator *alloc_ = nullptr; VkShaderModule vshader_ = VK_NULL_HANDLE; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 6fdbdb0ac5..6cc77e2784 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -77,10 +77,8 @@ enum { TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex) }; -DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan, Draw::DrawContext *draw) - : vulkan_(vulkan), - draw_(draw), - vai_(1024) { +DrawEngineVulkan::DrawEngineVulkan(Draw::DrawContext *draw) + : draw_(draw), vai_(1024) { decOptions_.expandAllWeightsToFloat = false; decOptions_.expand8BitNormalsToFloat = false; @@ -135,7 +133,8 @@ void DrawEngineVulkan::InitDeviceObjects() { bindings[8].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; bindings[8].binding = DRAW_BINDING_TESS_STORAGE_BUF_WV; - VkDevice device = vulkan_->GetDevice(); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + VkDevice device = vulkan->GetDevice(); VkDescriptorSetLayoutCreateInfo dsl{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; dsl.bindingCount = ARRAY_SIZE(bindings); @@ -149,11 +148,11 @@ void DrawEngineVulkan::InitDeviceObjects() { // We now create descriptor pools on demand, so removed from here. // Note that pushUBO is also used for tessellation data (search for SetPushBuffer), and to upload // the null texture. This should be cleaned up... - frame_[i].pushUBO = new VulkanPushBuffer(vulkan_, 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - frame_[i].pushVertex = new VulkanPushBuffer(vulkan_, 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - frame_[i].pushIndex = new VulkanPushBuffer(vulkan_, 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + frame_[i].pushUBO = new VulkanPushBuffer(vulkan, 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + frame_[i].pushVertex = new VulkanPushBuffer(vulkan, 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + frame_[i].pushIndex = new VulkanPushBuffer(vulkan, 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); - frame_[i].pushLocal = new VulkanPushBuffer(vulkan_, 1 * 1024 * 1024, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + frame_[i].pushLocal = new VulkanPushBuffer(vulkan, 1 * 1024 * 1024, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; @@ -178,9 +177,9 @@ void DrawEngineVulkan::InitDeviceObjects() { res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); _dbg_assert_(VK_SUCCESS == res); - vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan_); + tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan); tessDataTransfer = tessDataTransferVulkan; } @@ -219,23 +218,25 @@ void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) { } void DrawEngineVulkan::DestroyDeviceObjects() { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + delete tessDataTransferVulkan; tessDataTransfer = nullptr; tessDataTransferVulkan = nullptr; for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { - frame_[i].Destroy(vulkan_); + frame_[i].Destroy(vulkan); } if (samplerSecondary_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeleteSampler(samplerSecondary_); + vulkan->Delete().QueueDeleteSampler(samplerSecondary_); if (nullSampler_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeleteSampler(nullSampler_); + vulkan->Delete().QueueDeleteSampler(nullSampler_); if (pipelineLayout_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeletePipelineLayout(pipelineLayout_); + vulkan->Delete().QueueDeletePipelineLayout(pipelineLayout_); if (descriptorSetLayout_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_); + vulkan->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_); if (vertexCache_) { - vertexCache_->Destroy(vulkan_); + vertexCache_->Destroy(vulkan); delete vertexCache_; vertexCache_ = nullptr; } @@ -251,8 +252,7 @@ void DrawEngineVulkan::DeviceLost() { DirtyAllUBOs(); } -void DrawEngineVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) { - vulkan_ = vulkan; +void DrawEngineVulkan::DeviceRestore(Draw::DrawContext *draw) { draw_ = draw; InitDeviceObjects(); @@ -263,8 +263,7 @@ void DrawEngineVulkan::BeginFrame() { lastRenderStepId_ = -1; - int curFrame = vulkan_->GetCurFrame(); - FrameData *frame = &frame_[curFrame]; + FrameData *frame = &GetCurFrame(); // 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 @@ -275,10 +274,11 @@ void DrawEngineVulkan::BeginFrame() { frame->pushIndex->Reset(); frame->pushLocal->Reset(); - frame->pushUBO->Begin(vulkan_); - frame->pushVertex->Begin(vulkan_); - frame->pushIndex->Begin(vulkan_); - frame->pushLocal->Begin(vulkan_); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + frame->pushUBO->Begin(vulkan); + frame->pushVertex->Begin(vulkan); + frame->pushIndex->Begin(vulkan); + frame->pushLocal->Begin(vulkan); // TODO: How can we make this nicer... tessDataTransferVulkan->SetPushBuffer(frame->pushUBO); @@ -287,9 +287,9 @@ void DrawEngineVulkan::BeginFrame() { // Wipe the vertex cache if it's grown too large. if (vertexCache_->GetTotalSize() > VERTEX_CACHE_SIZE) { - vertexCache_->Destroy(vulkan_); + vertexCache_->Destroy(vulkan); delete vertexCache_; // orphans the buffers, they'll get deleted once no longer used by an in-flight frame. - vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); vai_.Iterate([&](uint32_t hash, VertexArrayInfoVulkan *vai) { delete vai; }); @@ -300,7 +300,7 @@ void DrawEngineVulkan::BeginFrame() { if (--descDecimationCounter_ <= 0) { if (frame->descPool != VK_NULL_HANDLE) - vkResetDescriptorPool(vulkan_->GetDevice(), frame->descPool, 0); + vkResetDescriptorPool(vulkan->GetDevice(), frame->descPool, 0); frame->descSets.Clear(); frame->descCount = 0; descDecimationCounter_ = DESCRIPTORSET_DECIMATION_INTERVAL; @@ -331,7 +331,7 @@ void DrawEngineVulkan::BeginFrame() { } void DrawEngineVulkan::EndFrame() { - FrameData *frame = &frame_[vulkan_->GetCurFrame()]; + FrameData *frame = &GetCurFrame(); stats_.pushUBOSpaceUsed = (int)frame->pushUBO->GetOffset(); stats_.pushVertexSpaceUsed = (int)frame->pushVertex->GetOffset(); stats_.pushIndexSpaceUsed = (int)frame->pushIndex->GetOffset(); @@ -354,11 +354,13 @@ void DrawEngineVulkan::DecodeVertsToPushBuffer(VulkanPushBuffer *push, uint32_t } VkResult DrawEngineVulkan::RecreateDescriptorPool(FrameData &frame, int newSize) { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + // Reallocate this desc pool larger, and "wipe" the cache. We might lose a tiny bit of descriptor set reuse but // only for this frame. if (frame.descPool) { DEBUG_LOG(G3D, "Reallocating desc pool from %d to %d", frame.descPoolSize, newSize); - vulkan_->Delete().QueueDeleteDescriptorPool(frame.descPool); + vulkan->Delete().QueueDeleteDescriptorPool(frame.descPool); frame.descSets.Clear(); frame.descCount = 0; } @@ -379,7 +381,7 @@ VkResult DrawEngineVulkan::RecreateDescriptorPool(FrameData &frame, int newSize) dp.pPoolSizes = dpTypes; dp.poolSizeCount = ARRAY_SIZE(dpTypes); - VkResult res = vkCreateDescriptorPool(vulkan_->GetDevice(), &dp, nullptr, &frame.descPool); + VkResult res = vkCreateDescriptorPool(vulkan->GetDevice(), &dp, nullptr, &frame.descPool); return res; } @@ -397,7 +399,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView key.light_ = light; key.bone_ = bone; - FrameData &frame = frame_[vulkan_->GetCurFrame()]; + FrameData &frame = GetCurFrame(); // See if we already have this descriptor set cached. if (!tess) { // Don't cache descriptors for HW tessellation. VkDescriptorSet d = frame.descSets.Get(key); @@ -413,12 +415,13 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView // Didn't find one in the frame descriptor set cache, let's make a new one. // We wipe the cache on every frame. + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); VkDescriptorSet desc; VkDescriptorSetAllocateInfo descAlloc{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; descAlloc.pSetLayouts = &descriptorSetLayout_; descAlloc.descriptorPool = frame.descPool; descAlloc.descriptorSetCount = 1; - VkResult result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); + VkResult result = vkAllocateDescriptorSets(vulkan->GetDevice(), &descAlloc, &desc); if (result == VK_ERROR_FRAGMENTED_POOL || result < 0) { // There seems to have been a spec revision. Here we should apparently recreate the descriptor pool, @@ -427,7 +430,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView VkResult res = RecreateDescriptorPool(frame, frame.descPoolSize); _assert_msg_(res == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to recreate a descriptor pool. sz=%d res=%d", (int)frame.descSets.size(), (int)res); descAlloc.descriptorPool = frame.descPool; // Need to update this pointer since we have allocated a new one. - result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); + result = vkAllocateDescriptorSets(vulkan->GetDevice(), &descAlloc, &desc); _assert_msg_(result == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to allocate after recreating a descriptor pool. res=%d", (int)result); } @@ -542,7 +545,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView n++; } - vkUpdateDescriptorSets(vulkan_->GetDevice(), n, writes, 0, nullptr); + vkUpdateDescriptorSets(vulkan->GetDevice(), n, writes, 0, nullptr); if (!tess) // Again, avoid caching when HW tessellation. frame.descSets.Insert(key, desc); @@ -592,7 +595,7 @@ void DrawEngineVulkan::DoFlush() { lastRenderStepId_ = curRenderStepId; } - FrameData *frame = &frame_[vulkan_->GetCurFrame()]; + FrameData *frame = &GetCurFrame(); bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE; @@ -1064,6 +1067,11 @@ void DrawEngineVulkan::UpdateUBOs(FrameData *frame) { } } +DrawEngineVulkan::FrameData &DrawEngineVulkan::GetCurFrame() { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + return frame_[vulkan->GetCurFrame()]; +} + void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) { // SSBOs that are not simply float1 or float2 need to be padded up to a float4 size. vec3 members // also need to be 16-byte aligned, hence the padding. diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 1507aaffce..cea9cb3546 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -123,7 +123,7 @@ private: // Handles transform, lighting and drawing. class DrawEngineVulkan : public DrawEngineCommon { public: - DrawEngineVulkan(VulkanContext *vulkan, Draw::DrawContext *draw); + DrawEngineVulkan(Draw::DrawContext *draw); virtual ~DrawEngineVulkan(); void SetShaderManager(ShaderManagerVulkan *shaderManager) { @@ -140,7 +140,7 @@ public: } void DeviceLost(); - void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw); + void DeviceRestore(Draw::DrawContext *draw); // So that this can be inlined void Flush() { @@ -174,12 +174,12 @@ public: } VulkanPushBuffer *GetPushBufferForTextureData() { - return frame_[vulkan_->GetCurFrame()].pushUBO; + return GetCurFrame().pushUBO; } // Only use Allocate on this one. VulkanPushBuffer *GetPushBufferLocal() { - return frame_[vulkan_->GetCurFrame()].pushLocal; + return GetCurFrame().pushLocal; } const DrawEngineVulkanStats &GetStats() const { @@ -208,10 +208,10 @@ private: void DoFlush(); void UpdateUBOs(FrameData *frame); + FrameData &GetCurFrame(); VkDescriptorSet GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone, bool tess); - VulkanContext *vulkan_; Draw::DrawContext *draw_; // We use a single descriptor set layout for all PSP draws. diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 91572e147d..314eb3e0b8 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -74,9 +74,8 @@ void main() { } )"; -FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan) : - FramebufferManagerCommon(draw), - vulkan_(vulkan) { +FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw) : + FramebufferManagerCommon(draw) { presentation_->SetLanguage(GLSL_VULKAN); InitDeviceObjects(); @@ -102,9 +101,10 @@ void FramebufferManagerVulkan::SetDrawEngine(DrawEngineVulkan *td) { } void FramebufferManagerVulkan::InitDeviceObjects() { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); std::string fs_errors, vs_errors; - fsBasicTex_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_FRAGMENT_BIT, tex_fs, &fs_errors); - vsBasicTex_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, tex_vs, &vs_errors); + fsBasicTex_ = CompileShaderModule(vulkan, VK_SHADER_STAGE_FRAGMENT_BIT, tex_fs, &fs_errors); + vsBasicTex_ = CompileShaderModule(vulkan, VK_SHADER_STAGE_VERTEX_BIT, tex_vs, &vs_errors); _assert_(fsBasicTex_ != VK_NULL_HANDLE); _assert_(vsBasicTex_ != VK_NULL_HANDLE); @@ -114,36 +114,39 @@ void FramebufferManagerVulkan::InitDeviceObjects() { samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samp.magFilter = VK_FILTER_NEAREST; samp.minFilter = VK_FILTER_NEAREST; - VkResult res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &nearestSampler_); + VkResult res = vkCreateSampler(vulkan->GetDevice(), &samp, nullptr, &nearestSampler_); _assert_(res == VK_SUCCESS); samp.magFilter = VK_FILTER_LINEAR; samp.minFilter = VK_FILTER_LINEAR; - res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &linearSampler_); + res = vkCreateSampler(vulkan->GetDevice(), &samp, nullptr, &linearSampler_); _assert_(res == VK_SUCCESS); } void FramebufferManagerVulkan::DestroyDeviceObjects() { + if (!draw_) + return; + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); if (fsBasicTex_ != VK_NULL_HANDLE) { vulkan2D_->PurgeFragmentShader(fsBasicTex_); - vulkan_->Delete().QueueDeleteShaderModule(fsBasicTex_); + vulkan->Delete().QueueDeleteShaderModule(fsBasicTex_); } if (vsBasicTex_ != VK_NULL_HANDLE) { vulkan2D_->PurgeVertexShader(vsBasicTex_); - vulkan_->Delete().QueueDeleteShaderModule(vsBasicTex_); + vulkan->Delete().QueueDeleteShaderModule(vsBasicTex_); } if (stencilFs_ != VK_NULL_HANDLE) { vulkan2D_->PurgeFragmentShader(stencilFs_); - vulkan_->Delete().QueueDeleteShaderModule(stencilFs_); + vulkan->Delete().QueueDeleteShaderModule(stencilFs_); } if (stencilVs_ != VK_NULL_HANDLE) { vulkan2D_->PurgeVertexShader(stencilVs_); - vulkan_->Delete().QueueDeleteShaderModule(stencilVs_); + vulkan->Delete().QueueDeleteShaderModule(stencilVs_); } if (linearSampler_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeleteSampler(linearSampler_); + vulkan->Delete().QueueDeleteSampler(linearSampler_); if (nearestSampler_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeleteSampler(nearestSampler_); + vulkan->Delete().QueueDeleteSampler(nearestSampler_); } void FramebufferManagerVulkan::NotifyClear(bool clearColor, bool clearAlpha, bool clearDepth, uint32_t color, float depth) { @@ -313,12 +316,11 @@ void FramebufferManagerVulkan::EndFrame() { } void FramebufferManagerVulkan::DeviceLost() { - FramebufferManagerCommon::DeviceLost(); DestroyDeviceObjects(); + FramebufferManagerCommon::DeviceLost(); } void FramebufferManagerVulkan::DeviceRestore(Draw::DrawContext *draw) { FramebufferManagerCommon::DeviceRestore(draw); - vulkan_ = (VulkanContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); InitDeviceObjects(); } diff --git a/GPU/Vulkan/FramebufferManagerVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h index 0642cbac43..6e8725398a 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.h +++ b/GPU/Vulkan/FramebufferManagerVulkan.h @@ -34,7 +34,7 @@ class VulkanPushBuffer; class FramebufferManagerVulkan : public FramebufferManagerCommon { public: - FramebufferManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan); + FramebufferManagerVulkan(Draw::DrawContext *draw); ~FramebufferManagerVulkan(); void SetTextureCache(TextureCacheVulkan *tc); @@ -68,8 +68,6 @@ private: void InitDeviceObjects(); void DestroyDeviceObjects(); - VulkanContext *vulkan_; - // Used to keep track of command buffers here but have moved all that into Thin3D. VulkanPushBuffer *push_; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index c8184315ee..f6b12f8cc7 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -53,17 +53,17 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : GPUCommon(gfxCtx, draw), - vulkan_((VulkanContext *)gfxCtx->GetAPIContext()), - depalShaderCache_(draw, vulkan_), - drawEngine_(vulkan_, draw), - vulkan2D_(vulkan_) { + depalShaderCache_(draw), + drawEngine_(draw), + vulkan2D_((VulkanContext *)gfxCtx->GetAPIContext()) { CheckGPUFeatures(); - shaderManagerVulkan_ = new ShaderManagerVulkan(draw, vulkan_); - pipelineManager_ = new PipelineManagerVulkan(vulkan_); - framebufferManagerVulkan_ = new FramebufferManagerVulkan(draw, vulkan_); + VulkanContext *vulkan = (VulkanContext *)gfxCtx->GetAPIContext(); + shaderManagerVulkan_ = new ShaderManagerVulkan(draw); + pipelineManager_ = new PipelineManagerVulkan(vulkan); + framebufferManagerVulkan_ = new FramebufferManagerVulkan(draw); framebufferManager_ = framebufferManagerVulkan_; - textureCacheVulkan_ = new TextureCacheVulkan(draw, vulkan_); + textureCacheVulkan_ = new TextureCacheVulkan(draw, vulkan); textureCache_ = textureCacheVulkan_; drawEngineCommon_ = &drawEngine_; shaderManager_ = shaderManagerVulkan_; @@ -182,7 +182,8 @@ GPU_Vulkan::~GPU_Vulkan() { void GPU_Vulkan::CheckGPUFeatures() { uint32_t features = 0; - switch (vulkan_->GetPhysicalDeviceProperties().properties.vendorID) { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + switch (vulkan->GetPhysicalDeviceProperties().properties.vendorID) { case VULKAN_VENDOR_AMD: // Accurate depth is required on AMD (due to reverse-Z driver bug) so we ignore the compat flag to disable it on those. See #9545 features |= GPU_SUPPORTS_ACCURATE_DEPTH; @@ -194,8 +195,8 @@ void GPU_Vulkan::CheckGPUFeatures() { case VULKAN_VENDOR_ARM: { // This check is probably not exactly accurate. But old drivers had problems with reverse-Z, just like AMD and Qualcomm. - bool driverTooOld = IsHashMaliDriverVersion(vulkan_->GetPhysicalDeviceProperties().properties) - || VK_VERSION_MAJOR(vulkan_->GetPhysicalDeviceProperties().properties.driverVersion) < 14; + bool driverTooOld = IsHashMaliDriverVersion(vulkan->GetPhysicalDeviceProperties().properties) + || VK_VERSION_MAJOR(vulkan->GetPhysicalDeviceProperties().properties.driverVersion) < 14; if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || driverTooOld) { features |= GPU_SUPPORTS_ACCURATE_DEPTH; } @@ -223,11 +224,11 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_FLOAT; features |= GPU_SUPPORTS_DEPTH_TEXTURE; - if (vulkan_->GetDeviceInfo().canBlitToPreferredDepthStencilFormat) { + if (vulkan->GetDeviceInfo().canBlitToPreferredDepthStencilFormat) { features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT_TO_DEPTH; } - auto &enabledFeatures = vulkan_->GetDeviceFeatures().enabled; + auto &enabledFeatures = vulkan->GetDeviceFeatures().enabled; if (enabledFeatures.depthClamp) { features |= GPU_SUPPORTS_DEPTH_CLAMP; } @@ -307,11 +308,12 @@ void GPU_Vulkan::BeginHostFrame() { textureCacheVulkan_->StartFrame(); - int curFrame = vulkan_->GetCurFrame(); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + int curFrame = vulkan->GetCurFrame(); FrameData &frame = frameData_[curFrame]; frame.push_->Reset(); - frame.push_->Begin(vulkan_); + frame.push_->Begin(vulkan); framebufferManagerVulkan_->BeginFrameVulkan(); framebufferManagerVulkan_->SetPushBuffer(frameData_[curFrame].push_); @@ -333,7 +335,8 @@ void GPU_Vulkan::BeginHostFrame() { } void GPU_Vulkan::EndHostFrame() { - int curFrame = vulkan_->GetCurFrame(); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + int curFrame = vulkan->GetCurFrame(); FrameData &frame = frameData_[curFrame]; frame.push_->End(); @@ -348,8 +351,9 @@ void GPU_Vulkan::EndHostFrame() { // Needs to be called on GPU thread, not reporting thread. void GPU_Vulkan::BuildReportingInfo() { - const auto &props = vulkan_->GetPhysicalDeviceProperties().properties; - const auto &features = vulkan_->GetDeviceFeatures().available; + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + const auto &props = vulkan->GetPhysicalDeviceProperties().properties; + const auto &features = vulkan->GetDeviceFeatures().available; #define CHECK_BOOL_FEATURE(n) do { if (features.n) { featureNames += ", " #n; } } while (false) @@ -482,11 +486,12 @@ void GPU_Vulkan::ExecuteOp(u32 op, u32 diff) { void GPU_Vulkan::InitDeviceObjects() { INFO_LOG(G3D, "GPU_Vulkan::InitDeviceObjects"); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); // Initialize framedata for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { _assert_(!frameData_[i].push_); VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - frameData_[i].push_ = new VulkanPushBuffer(vulkan_, 256 * 1024, usage); + frameData_[i].push_ = new VulkanPushBuffer(vulkan, 256 * 1024, usage); } VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); @@ -506,9 +511,10 @@ void GPU_Vulkan::InitDeviceObjects() { void GPU_Vulkan::DestroyDeviceObjects() { INFO_LOG(G3D, "GPU_Vulkan::DestroyDeviceObjects"); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { if (frameData_[i].push_) { - frameData_[i].push_->Destroy(vulkan_); + frameData_[i].push_->Destroy(vulkan); delete frameData_[i].push_; frameData_[i].push_ = nullptr; } @@ -543,19 +549,19 @@ void GPU_Vulkan::DeviceLost() { void GPU_Vulkan::DeviceRestore() { GPUCommon::DeviceRestore(); - vulkan_ = (VulkanContext *)PSP_CoreParameter().graphicsContext->GetAPIContext(); InitDeviceObjects(); CheckGPUFeatures(); BuildReportingInfo(); UpdateCmdInfo(); - vulkan2D_.DeviceRestore(vulkan_); - drawEngine_.DeviceRestore(vulkan_, draw_); - pipelineManager_->DeviceRestore(vulkan_); - textureCacheVulkan_->DeviceRestore(vulkan_, draw_); - shaderManagerVulkan_->DeviceRestore(vulkan_, draw_); - depalShaderCache_.DeviceRestore(draw_, vulkan_); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + vulkan2D_.DeviceRestore(vulkan); + drawEngine_.DeviceRestore(draw_); + pipelineManager_->DeviceRestore(vulkan); + textureCacheVulkan_->DeviceRestore(draw_); + shaderManagerVulkan_->DeviceRestore(draw_); + depalShaderCache_.DeviceRestore(draw_); } void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) { diff --git a/GPU/Vulkan/GPU_Vulkan.h b/GPU/Vulkan/GPU_Vulkan.h index 2cd6edb16a..fcff7e5790 100644 --- a/GPU/Vulkan/GPU_Vulkan.h +++ b/GPU/Vulkan/GPU_Vulkan.h @@ -89,7 +89,6 @@ private: void LoadCache(const Path &filename); void SaveCache(const Path &filename); - VulkanContext *vulkan_; FramebufferManagerVulkan *framebufferManagerVulkan_; TextureCacheVulkan *textureCacheVulkan_; DepalShaderCacheVulkan depalShaderCache_; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index ef2d7eb7e4..7954278a4a 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -157,10 +157,11 @@ std::string VulkanVertexShader::GetShaderString(DebugShaderStringType type) cons } } -ShaderManagerVulkan::ShaderManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan) - : ShaderManagerCommon(draw), vulkan_(vulkan), compat_(GLSL_VULKAN), fsCache_(16), vsCache_(16) { +ShaderManagerVulkan::ShaderManagerVulkan(Draw::DrawContext *draw) + : ShaderManagerCommon(draw), compat_(GLSL_VULKAN), fsCache_(16), vsCache_(16) { codeBuffer_ = new char[16384]; - uboAlignment_ = vulkan_->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment; + VulkanContext *vulkan = (VulkanContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); + uboAlignment_ = vulkan->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment; memset(&ub_base, 0, sizeof(ub_base)); memset(&ub_lights, 0, sizeof(ub_lights)); memset(&ub_bones, 0, sizeof(ub_bones)); @@ -175,10 +176,10 @@ ShaderManagerVulkan::~ShaderManagerVulkan() { delete[] codeBuffer_; } -void ShaderManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) { - vulkan_ = vulkan; +void ShaderManagerVulkan::DeviceRestore(Draw::DrawContext *draw) { + VulkanContext *vulkan = (VulkanContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); draw_ = draw; - uboAlignment_ = vulkan_->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment; + uboAlignment_ = vulkan->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment; } void ShaderManagerVulkan::Clear() { @@ -259,6 +260,7 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader return; } + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); VulkanVertexShader *vs = vsCache_.Get(VSID); if (!vs) { // Vertex shader not in cache. Let's compile it. @@ -267,20 +269,20 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader uint32_t attributeMask = 0; // Not used bool success = GenerateVertexShader(VSID, codeBuffer_, compat_, draw_->GetBugs(), &attributeMask, &uniformMask, &genErrorString); _assert_msg_(success, "VS gen error: %s", genErrorString.c_str()); - vs = new VulkanVertexShader(vulkan_, VSID, codeBuffer_, useHWTransform); + vs = new VulkanVertexShader(vulkan, VSID, codeBuffer_, useHWTransform); vsCache_.Insert(VSID, vs); } lastVSID_ = VSID; VulkanFragmentShader *fs = fsCache_.Get(FSID); if (!fs) { - // uint32_t vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID; + // uint32_t vendorID = vulkan->GetPhysicalDeviceProperties().properties.vendorID; // Fragment shader not in cache. Let's compile it. std::string genErrorString; uint64_t uniformMask = 0; // Not used bool success = GenerateFragmentShader(FSID, codeBuffer_, compat_, draw_->GetBugs(), &uniformMask, &genErrorString); _assert_msg_(success, "FS gen error: %s", genErrorString.c_str()); - fs = new VulkanFragmentShader(vulkan_, FSID, codeBuffer_); + fs = new VulkanFragmentShader(vulkan, FSID, codeBuffer_); fsCache_.Insert(FSID, fs); } @@ -388,6 +390,7 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) { if (header.featureFlags != gstate_c.featureFlags) return false; + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); for (int i = 0; i < header.numVertexShaders; i++) { VShaderID id; if (fread(&id, sizeof(id), 1, f) != 1) { @@ -401,10 +404,10 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) { if (!GenerateVertexShader(id, codeBuffer_, compat_, draw_->GetBugs(), &attributeMask, &uniformMask, &genErrorString)) { return false; } - VulkanVertexShader *vs = new VulkanVertexShader(vulkan_, id, codeBuffer_, useHWTransform); + VulkanVertexShader *vs = new VulkanVertexShader(vulkan, id, codeBuffer_, useHWTransform); vsCache_.Insert(id, vs); } - uint32_t vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID; + uint32_t vendorID = vulkan->GetPhysicalDeviceProperties().properties.vendorID; for (int i = 0; i < header.numFragmentShaders; i++) { FShaderID id; @@ -417,7 +420,7 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) { if (!GenerateFragmentShader(id, codeBuffer_, compat_, draw_->GetBugs(), &uniformMask, &genErrorString)) { return false; } - VulkanFragmentShader *fs = new VulkanFragmentShader(vulkan_, id, codeBuffer_); + VulkanFragmentShader *fs = new VulkanFragmentShader(vulkan, id, codeBuffer_); fsCache_.Insert(id, fs); } diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index c9aa297d02..e3fbfd9395 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -83,10 +83,10 @@ class VulkanPushBuffer; class ShaderManagerVulkan : public ShaderManagerCommon { public: - ShaderManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan); + ShaderManagerVulkan(Draw::DrawContext *draw); ~ShaderManagerVulkan(); - void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw); + void DeviceRestore(Draw::DrawContext *draw); void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat); void ClearShaders(); @@ -130,7 +130,6 @@ public: private: void Clear(); - VulkanContext *vulkan_; ShaderLanguageDesc compat_; typedef DenseHashMap FSCache; diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 53d2cd34cd..bc03130293 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -147,14 +147,16 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp std::string error; if (!stencilVs_) { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + const char *stencil_fs_source = stencil_fs; // See comment above the stencil_fs_adreno definition. - u32 vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID; + u32 vendorID = vulkan->GetPhysicalDeviceProperties().properties.vendorID; if (g_Config.bVendorBugChecksEnabled && (draw_->GetBugs().Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL) || vendorID == VULKAN_VENDOR_ARM)) stencil_fs_source = stencil_fs_adreno; - stencilVs_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, stencil_vs, &error); - stencilFs_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_FRAGMENT_BIT, stencil_fs_source, &error); + stencilVs_ = CompileShaderModule(vulkan, VK_SHADER_STAGE_VERTEX_BIT, stencil_vs, &error); + stencilFs_ = CompileShaderModule(vulkan, VK_SHADER_STAGE_FRAGMENT_BIT, stencil_fs_source, &error); } VkRenderPass rp = (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::FRAMEBUFFER_RENDERPASS); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 44f8ca28b7..c3396e3982 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -180,10 +180,9 @@ std::vector SamplerCache::DebugGetSamplerIDs() const { TextureCacheVulkan::TextureCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan) : TextureCacheCommon(draw), - vulkan_(vulkan), computeShaderManager_(vulkan), samplerCache_(vulkan) { - DeviceRestore(vulkan, draw); + DeviceRestore(draw); SetupTextureDecoder(); } @@ -192,7 +191,6 @@ TextureCacheVulkan::~TextureCacheVulkan() { } void TextureCacheVulkan::SetFramebufferManager(FramebufferManagerVulkan *fbManager) { - framebufferManagerVulkan_ = fbManager; framebufferManager_ = fbManager; } @@ -202,13 +200,15 @@ void TextureCacheVulkan::SetVulkan2D(Vulkan2D *vk2d) { } void TextureCacheVulkan::DeviceLost() { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + Clear(true); if (allocator_) { allocator_->Destroy(); // We have to delete on queue, so this can free its queued deletions. - vulkan_->Delete().QueueCallback([](void *ptr) { + vulkan->Delete().QueueCallback([](void *ptr) { auto allocator = static_cast(ptr); delete allocator; }, allocator_); @@ -218,23 +218,23 @@ void TextureCacheVulkan::DeviceLost() { samplerCache_.DeviceLost(); if (samplerNearest_) - vulkan_->Delete().QueueDeleteSampler(samplerNearest_); + vulkan->Delete().QueueDeleteSampler(samplerNearest_); if (uploadCS_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeleteShaderModule(uploadCS_); + vulkan->Delete().QueueDeleteShaderModule(uploadCS_); computeShaderManager_.DeviceLost(); nextTexture_ = nullptr; } -void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) { - vulkan_ = vulkan; +void TextureCacheVulkan::DeviceRestore(Draw::DrawContext *draw) { + VulkanContext *vulkan = (VulkanContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); draw_ = draw; _assert_(!allocator_); - allocator_ = new VulkanDeviceAllocator(vulkan_, TEXCACHE_MIN_SLAB_SIZE, TEXCACHE_MAX_SLAB_SIZE); + allocator_ = new VulkanDeviceAllocator(vulkan, TEXCACHE_MIN_SLAB_SIZE, TEXCACHE_MAX_SLAB_SIZE); samplerCache_.DeviceRestore(vulkan); VkSamplerCreateInfo samp{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; @@ -244,7 +244,7 @@ void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext samp.magFilter = VK_FILTER_NEAREST; samp.minFilter = VK_FILTER_NEAREST; samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - VkResult res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &samplerNearest_); + VkResult res = vkCreateSampler(vulkan->GetDevice(), &samp, nullptr, &samplerNearest_); _assert_(res == VK_SUCCESS); CompileScalingShader(); @@ -269,9 +269,11 @@ static std::string ReadShaderSrc(const Path &filename) { } void TextureCacheVulkan::CompileScalingShader() { + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + if (!g_Config.bTexHardwareScaling || g_Config.sTextureShaderName != textureShader_) { if (uploadCS_ != VK_NULL_HANDLE) - vulkan_->Delete().QueueDeleteShaderModule(uploadCS_); + vulkan->Delete().QueueDeleteShaderModule(uploadCS_); textureShader_.clear(); shaderScaleFactor_ = 0; // no texture scaling shader } else if (uploadCS_) { @@ -291,7 +293,7 @@ void TextureCacheVulkan::CompileScalingShader() { std::string fullUploadShader = StringFromFormat(uploadShader, shaderSource.c_str()); std::string error; - uploadCS_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_COMPUTE_BIT, fullUploadShader.c_str(), &error); + uploadCS_ = CompileShaderModule(vulkan, VK_SHADER_STAGE_COMPUTE_BIT, fullUploadShader.c_str(), &error); _dbg_assert_msg_(uploadCS_ != VK_NULL_HANDLE, "failed to compile upload shader"); textureShader_ = g_Config.sTextureShaderName; @@ -441,7 +443,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer TexCacheEntry::TexStatus alphaStatus = CheckAlpha(clutBuf_, getClutDestFormatVulkan(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey); - if (framebufferManagerVulkan_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET)) { + if (framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET)) { imageView_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW); } else { imageView_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::NULL_IMAGEVIEW); @@ -554,7 +556,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer // Since we may have switched render targets, we need to re-set depth/stencil etc states. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); } else { - if (framebufferManagerVulkan_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET)) { + if (framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET)) { imageView_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW); } else { imageView_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::NULL_IMAGEVIEW); @@ -709,10 +711,11 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { bool computeUpload = false; VkCommandBuffer cmdInit = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); { delete entry->vkTex; - entry->vkTex = new VulkanTexture(vulkan_); + entry->vkTex = new VulkanTexture(vulkan); VulkanTexture *image = entry->vkTex; const VkComponentMapping *mapping; @@ -812,7 +815,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { uint32_t bufferOffset; VkBuffer texBuf; // NVIDIA reports a min alignment of 1 but that can't be healthy... let's align by 16 as a minimum. - int pushAlignment = std::max(16, (int)vulkan_->GetPhysicalDeviceProperties().properties.limits.optimalBufferCopyOffsetAlignment); + int pushAlignment = std::max(16, (int)vulkan->GetPhysicalDeviceProperties().properties.limits.optimalBufferCopyOffsetAlignment); void *data; bool dataScaled = true; if (replaced.Valid()) { @@ -845,7 +848,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { vkCmdBindDescriptorSets(cmdInit, VK_PIPELINE_BIND_POINT_COMPUTE, computeShaderManager_.GetPipelineLayout(), 0, 1, &descSet, 0, nullptr); vkCmdPushConstants(cmdInit, computeShaderManager_.GetPipelineLayout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(params), ¶ms); vkCmdDispatch(cmdInit, (mipUnscaledWidth + 7) / 8, (mipUnscaledHeight + 7) / 8, 1); - vulkan_->Delete().QueueDeleteImageView(view); + vulkan->Delete().QueueDeleteImageView(view); } else { data = drawEngine_->GetPushBufferForTextureData()->PushAligned(size, &bufferOffset, &texBuf, pushAlignment); LoadTextureLevel(*entry, (uint8_t *)data, stride, i, scaleFactor, dstFmt); diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index da2cf9ee76..da228ffac4 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -66,7 +66,7 @@ public: void EndFrame(); void DeviceLost(); - void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw); + void DeviceRestore(Draw::DrawContext *draw); void SetFramebufferManager(FramebufferManagerVulkan *fbManager); void SetDepalShaderCache(DepalShaderCacheVulkan *dpCache) { @@ -118,7 +118,6 @@ private: void CompileScalingShader(); - VulkanContext *vulkan_ = nullptr; VulkanDeviceAllocator *allocator_ = nullptr; VulkanPushBuffer *push_ = nullptr; @@ -128,7 +127,6 @@ private: TextureScalerVulkan scaler; - FramebufferManagerVulkan *framebufferManagerVulkan_; DepalShaderCacheVulkan *depalShaderCache_; ShaderManagerVulkan *shaderManagerVulkan_; DrawEngineVulkan *drawEngine_;