ppsspp/GPU/Vulkan/PipelineManagerVulkan.h
Henrik Rydgård 3e749a94ce Vulkan: Fix bug where we ended up creating duplicate pipelines even if vertices decoded to the same format, if they were created from different formats.
This can cut down the number of pipelines to a third or less in some
games. However, benefit is likely smaller since Vulkan drivers will
deduplicate shaders inside each vkPipelineCache object.

Helps #10106 while not actually implementing any of the suggestions inside.
2017-11-13 11:22:33 +01:00

98 lines
2.7 KiB
C++

// Copyright (c) 2015- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include "Common/Hashmaps.h"
#include "GPU/Common/VertexDecoderCommon.h"
#include "GPU/Common/ShaderId.h"
#include "GPU/Vulkan/VulkanUtil.h"
#include "GPU/Vulkan/StateMappingVulkan.h"
// PSP vertex format.
enum class PspAttributeLocation {
POSITION = 0,
TEXCOORD = 1,
NORMAL = 2,
W1 = 3,
W2 = 4,
COLOR0 = 5,
COLOR1 = 6,
COUNT
};
struct VulkanPipelineKey {
VulkanPipelineRasterStateKey raster; // prim is included here
VkRenderPass renderPass;
bool useHWTransform;
uint32_t vtxDecId;
VkShaderModule vShader;
VkShaderModule fShader;
void ToString(std::string *str) const {
str->resize(sizeof(*this));
memcpy(&(*str)[0], this, sizeof(*this));
}
void FromString(const std::string &str) {
memcpy(this, &str[0], sizeof(*this));
}
};
enum {
UB_VS_FS_BASE = (1 << 0),
UB_VS_BONES = (1 << 1),
UB_VS_LIGHTS = (1 << 2),
};
// Simply wraps a Vulkan pipeline, providing some metadata.
struct VulkanPipeline {
VkPipeline pipeline;
int uniformBlocks; // UB_ enum above.
bool useBlendConstant;
bool usesLines;
};
class VulkanContext;
class VulkanVertexShader;
class VulkanFragmentShader;
class PipelineManagerVulkan {
public:
PipelineManagerVulkan(VulkanContext *ctx);
~PipelineManagerVulkan();
VulkanPipeline *GetOrCreatePipeline(VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform);
int GetNumPipelines() const { return (int)pipelines_.size(); }
void Clear();
void SetLineWidth(float lw);
void DeviceLost();
void DeviceRestore(VulkanContext *vulkan);
std::string DebugGetObjectString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
std::vector<std::string> DebugGetObjectIDs(DebugShaderType type);
private:
DenseHashMap<VulkanPipelineKey, VulkanPipeline *, nullptr> pipelines_;
VkPipelineCache pipelineCache_;
VulkanContext *vulkan_;
float lineWidth_ = 1.0f;
};