mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Vulkan: De-duplicate pipelines when storing cache
The new variety of renderpasses with different transitions causes duplication. Hopefully drivers are smart enough to re-use work between similar pipelines as much as possible...
This commit is contained in:
parent
1dabccb453
commit
8f87a9f5c5
@ -135,10 +135,11 @@ public:
|
||||
bool EnableDeviceExtension(const char *extension);
|
||||
VkResult CreateDevice();
|
||||
|
||||
const std::string &InitError() { return init_error_; }
|
||||
const std::string &InitError() const { return init_error_; }
|
||||
|
||||
VkDevice GetDevice() { return device_; }
|
||||
VkInstance GetInstance() { return instance_; }
|
||||
VkDevice GetDevice() const { return device_; }
|
||||
VkInstance GetInstance() const { return instance_; }
|
||||
uint32_t GetFlags() const { return flags_; }
|
||||
|
||||
VulkanDeleteList &Delete() { return globalDeleteList_; }
|
||||
|
||||
|
@ -58,6 +58,12 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
||||
image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
// The graphics debugger always "needs" TRANSFER_SRC but in practice doesn't matter -
|
||||
// unless validation is on. So let's only force it on when being validated, for now.
|
||||
if (vulkan_->GetFlags() & VULKAN_FLAG_VALIDATE) {
|
||||
image_create_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
}
|
||||
|
||||
VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image_);
|
||||
if (res != VK_SUCCESS) {
|
||||
_assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "profiler/profiler.h"
|
||||
|
||||
@ -526,12 +527,14 @@ void PipelineManagerVulkan::SaveCache(FILE *file, bool saveRawPipelineCache, Sha
|
||||
}
|
||||
|
||||
size_t seekPosOnFailure = ftell(file);
|
||||
// Write the number of pipelines.
|
||||
size = (uint32_t)pipelines_.size();
|
||||
fwrite(&size, sizeof(size), 1, file);
|
||||
|
||||
bool failed = false;
|
||||
int count = 0;
|
||||
// Since we don't include the full pipeline key, there can be duplicates,
|
||||
// caused by things like switching from buffered to non-buffered rendering.
|
||||
// Make sure the set of pipelines we write is "unique".
|
||||
std::set<StoredVulkanPipelineKey> keys;
|
||||
|
||||
pipelines_.Iterate([&](const VulkanPipelineKey &pkey, VulkanPipeline *value) {
|
||||
if (failed)
|
||||
return;
|
||||
@ -550,10 +553,18 @@ void PipelineManagerVulkan::SaveCache(FILE *file, bool saveRawPipelineCache, Sha
|
||||
// NOTE: This is not a vtype, but a decoded vertex format.
|
||||
key.vtxFmtId = pkey.vtxFmtId;
|
||||
}
|
||||
fwrite(&key, sizeof(key), 1, file);
|
||||
count++;
|
||||
keys.insert(key);
|
||||
});
|
||||
|
||||
// Write the number of pipelines.
|
||||
size = (uint32_t)keys.size();
|
||||
fwrite(&size, sizeof(size), 1, file);
|
||||
|
||||
// Write the pipelines.
|
||||
for (auto &key : keys) {
|
||||
fwrite(&key, sizeof(key), 1, file);
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
ERROR_LOG(G3D, "Failed to write pipeline cache, some shader was missing");
|
||||
// Write a zero in the right place so it doesn't try to load the pipelines next time.
|
||||
@ -562,7 +573,7 @@ void PipelineManagerVulkan::SaveCache(FILE *file, bool saveRawPipelineCache, Sha
|
||||
fwrite(&size, sizeof(size), 1, file);
|
||||
return;
|
||||
}
|
||||
NOTICE_LOG(G3D, "Saved Vulkan pipeline ID cache (%d pipelines).", (int)count);
|
||||
NOTICE_LOG(G3D, "Saved Vulkan pipeline ID cache (%d unique pipelines/%d).", (int)keys.size(), (int)pipelines_.size());
|
||||
}
|
||||
|
||||
bool PipelineManagerVulkan::LoadCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, DrawEngineCommon *drawEngine, VkPipelineLayout layout, VkRenderPass renderPass) {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include "Common/Hashmaps.h"
|
||||
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
@ -60,6 +61,11 @@ struct StoredVulkanPipelineKey {
|
||||
FShaderID fShaderID;
|
||||
uint32_t vtxFmtId;
|
||||
bool useHWTransform;
|
||||
|
||||
// For std::set. Better zero-initialize the struct properly for this to work.
|
||||
bool operator < (const StoredVulkanPipelineKey &other) const {
|
||||
return memcmp(this, &other, sizeof(*this)) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
enum PipelineFlags {
|
||||
|
@ -350,7 +350,7 @@ VulkanFragmentShader *ShaderManagerVulkan::GetFragmentShaderFromModule(VkShaderM
|
||||
// instantaneous.
|
||||
|
||||
#define CACHE_HEADER_MAGIC 0xff51f420
|
||||
#define CACHE_VERSION 5
|
||||
#define CACHE_VERSION 6
|
||||
struct VulkanCacheHeader {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
|
Loading…
Reference in New Issue
Block a user