Vulkan: Move shader/pipeline-related methods to ShaderCache
This commit is contained in:
parent
d23fd17e1a
commit
aff44684a4
|
@ -7,6 +7,7 @@ set(SRCS
|
||||||
PostProcessing.cpp
|
PostProcessing.cpp
|
||||||
RasterFont.cpp
|
RasterFont.cpp
|
||||||
Renderer.cpp
|
Renderer.cpp
|
||||||
|
ShaderCache.cpp
|
||||||
ShaderCompiler.cpp
|
ShaderCompiler.cpp
|
||||||
StateTracker.cpp
|
StateTracker.cpp
|
||||||
StagingBuffer.cpp
|
StagingBuffer.cpp
|
||||||
|
|
|
@ -435,8 +435,8 @@ void FramebufferManager::ReinterpretPixelData(int convtype)
|
||||||
|
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||||
m_efb_load_render_pass, g_object_cache->GetScreenQuadVertexShader(),
|
m_efb_load_render_pass, g_shader_cache->GetScreenQuadVertexShader(),
|
||||||
g_object_cache->GetScreenQuadGeometryShader(), pixel_shader);
|
g_shader_cache->GetScreenQuadGeometryShader(), pixel_shader);
|
||||||
|
|
||||||
RasterizationState rs_state = Util::GetNoCullRasterizationState();
|
RasterizationState rs_state = Util::GetNoCullRasterizationState();
|
||||||
rs_state.samples = m_efb_samples;
|
rs_state.samples = m_efb_samples;
|
||||||
|
@ -510,8 +510,8 @@ Texture2D* FramebufferManager::ResolveEFBDepthTexture(const VkRect2D& region)
|
||||||
// Draw using resolve shader to write the minimum depth of all samples to the resolve texture.
|
// Draw using resolve shader to write the minimum depth of all samples to the resolve texture.
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||||
m_depth_resolve_render_pass, g_object_cache->GetScreenQuadVertexShader(),
|
m_depth_resolve_render_pass, g_shader_cache->GetScreenQuadVertexShader(),
|
||||||
g_object_cache->GetScreenQuadGeometryShader(), m_ps_depth_resolve);
|
g_shader_cache->GetScreenQuadGeometryShader(), m_ps_depth_resolve);
|
||||||
draw.BeginRenderPass(m_depth_resolve_framebuffer, region);
|
draw.BeginRenderPass(m_depth_resolve_framebuffer, region);
|
||||||
draw.SetPSSampler(0, m_efb_depth_texture->GetView(), g_object_cache->GetPointSampler());
|
draw.SetPSSampler(0, m_efb_depth_texture->GetView(), g_object_cache->GetPointSampler());
|
||||||
draw.SetViewportAndScissor(region.offset.x, region.offset.y, region.extent.width,
|
draw.SetViewportAndScissor(region.offset.x, region.offset.y, region.extent.width,
|
||||||
|
@ -641,7 +641,7 @@ bool FramebufferManager::CompileConversionShaders()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
std::string header = g_object_cache->GetUtilityShaderHeader();
|
std::string header = g_shader_cache->GetUtilityShaderHeader();
|
||||||
DestroyConversionShaders();
|
DestroyConversionShaders();
|
||||||
|
|
||||||
m_ps_rgb8_to_rgba6 = Util::CompileAndCreateFragmentShader(header + RGB8_TO_RGBA6_SHADER_SOURCE);
|
m_ps_rgb8_to_rgba6 = Util::CompileAndCreateFragmentShader(header + RGB8_TO_RGBA6_SHADER_SOURCE);
|
||||||
|
@ -698,7 +698,7 @@ bool FramebufferManager::PopulateColorReadbackTexture()
|
||||||
|
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||||
m_copy_color_render_pass, g_object_cache->GetScreenQuadVertexShader(),
|
m_copy_color_render_pass, g_shader_cache->GetScreenQuadVertexShader(),
|
||||||
VK_NULL_HANDLE, m_copy_color_shader);
|
VK_NULL_HANDLE, m_copy_color_shader);
|
||||||
|
|
||||||
VkRect2D rect = {{0, 0}, {EFB_WIDTH, EFB_HEIGHT}};
|
VkRect2D rect = {{0, 0}, {EFB_WIDTH, EFB_HEIGHT}};
|
||||||
|
@ -781,7 +781,7 @@ bool FramebufferManager::PopulateDepthReadbackTexture()
|
||||||
|
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||||
m_copy_depth_render_pass, g_object_cache->GetScreenQuadVertexShader(),
|
m_copy_depth_render_pass, g_shader_cache->GetScreenQuadVertexShader(),
|
||||||
VK_NULL_HANDLE, m_copy_depth_shader);
|
VK_NULL_HANDLE, m_copy_depth_shader);
|
||||||
|
|
||||||
VkRect2D rect = {{0, 0}, {EFB_WIDTH, EFB_HEIGHT}};
|
VkRect2D rect = {{0, 0}, {EFB_WIDTH, EFB_HEIGHT}};
|
||||||
|
@ -956,10 +956,10 @@ bool FramebufferManager::CompileReadbackShaders()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
source = g_object_cache->GetUtilityShaderHeader() + COPY_COLOR_SHADER_SOURCE;
|
source = g_shader_cache->GetUtilityShaderHeader() + COPY_COLOR_SHADER_SOURCE;
|
||||||
m_copy_color_shader = Util::CompileAndCreateFragmentShader(source);
|
m_copy_color_shader = Util::CompileAndCreateFragmentShader(source);
|
||||||
|
|
||||||
source = g_object_cache->GetUtilityShaderHeader() + COPY_DEPTH_SHADER_SOURCE;
|
source = g_shader_cache->GetUtilityShaderHeader() + COPY_DEPTH_SHADER_SOURCE;
|
||||||
m_copy_depth_shader = Util::CompileAndCreateFragmentShader(source);
|
m_copy_depth_shader = Util::CompileAndCreateFragmentShader(source);
|
||||||
|
|
||||||
return m_copy_color_shader != VK_NULL_HANDLE && m_copy_depth_shader != VK_NULL_HANDLE;
|
return m_copy_color_shader != VK_NULL_HANDLE && m_copy_depth_shader != VK_NULL_HANDLE;
|
||||||
|
@ -1176,7 +1176,7 @@ void FramebufferManager::DrawPokeVertices(const EFBPokeVertex* vertices, size_t
|
||||||
pipeline_info.depth_stencil_state.compare_op = VK_COMPARE_OP_ALWAYS;
|
pipeline_info.depth_stencil_state.compare_op = VK_COMPARE_OP_ALWAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline pipeline = g_object_cache->GetPipeline(pipeline_info);
|
VkPipeline pipeline = g_shader_cache->GetPipeline(pipeline_info);
|
||||||
if (pipeline == VK_NULL_HANDLE)
|
if (pipeline == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to get pipeline for EFB poke draw");
|
PanicAlert("Failed to get pipeline for EFB poke draw");
|
||||||
|
@ -1309,7 +1309,7 @@ bool FramebufferManager::CompilePokeShaders()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
std::string source = g_object_cache->GetUtilityShaderHeader();
|
std::string source = g_shader_cache->GetUtilityShaderHeader();
|
||||||
if (m_poke_primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
|
if (m_poke_primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
|
||||||
source += "#define USE_POINT_SIZE 1\n";
|
source += "#define USE_POINT_SIZE 1\n";
|
||||||
source += POKE_VERTEX_SHADER_SOURCE;
|
source += POKE_VERTEX_SHADER_SOURCE;
|
||||||
|
@ -1319,13 +1319,13 @@ bool FramebufferManager::CompilePokeShaders()
|
||||||
|
|
||||||
if (g_vulkan_context->SupportsGeometryShaders())
|
if (g_vulkan_context->SupportsGeometryShaders())
|
||||||
{
|
{
|
||||||
source = g_object_cache->GetUtilityShaderHeader() + POKE_GEOMETRY_SHADER_SOURCE;
|
source = g_shader_cache->GetUtilityShaderHeader() + POKE_GEOMETRY_SHADER_SOURCE;
|
||||||
m_poke_geometry_shader = Util::CompileAndCreateGeometryShader(source);
|
m_poke_geometry_shader = Util::CompileAndCreateGeometryShader(source);
|
||||||
if (m_poke_geometry_shader == VK_NULL_HANDLE)
|
if (m_poke_geometry_shader == VK_NULL_HANDLE)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
source = g_object_cache->GetUtilityShaderHeader() + POKE_PIXEL_SHADER_SOURCE;
|
source = g_shader_cache->GetUtilityShaderHeader() + POKE_PIXEL_SHADER_SOURCE;
|
||||||
m_poke_fragment_shader = Util::CompileAndCreateFragmentShader(source);
|
m_poke_fragment_shader = Util::CompileAndCreateFragmentShader(source);
|
||||||
if (m_poke_fragment_shader == VK_NULL_HANDLE)
|
if (m_poke_fragment_shader == VK_NULL_HANDLE)
|
||||||
return false;
|
return false;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,52 +27,6 @@ class CommandBufferManager;
|
||||||
class VertexFormat;
|
class VertexFormat;
|
||||||
class StreamBuffer;
|
class StreamBuffer;
|
||||||
|
|
||||||
struct PipelineInfo
|
|
||||||
{
|
|
||||||
// These are packed in descending order of size, to avoid any padding so that the structure
|
|
||||||
// can be copied/compared as a single block of memory. 64-bit pointer size is assumed.
|
|
||||||
const VertexFormat* vertex_format;
|
|
||||||
VkPipelineLayout pipeline_layout;
|
|
||||||
VkShaderModule vs;
|
|
||||||
VkShaderModule gs;
|
|
||||||
VkShaderModule ps;
|
|
||||||
VkRenderPass render_pass;
|
|
||||||
BlendingState blend_state;
|
|
||||||
RasterizationState rasterization_state;
|
|
||||||
DepthStencilState depth_stencil_state;
|
|
||||||
VkPrimitiveTopology primitive_topology;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PipelineInfoHash
|
|
||||||
{
|
|
||||||
std::size_t operator()(const PipelineInfo& key) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
|
||||||
bool operator!=(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
|
||||||
bool operator<(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
|
||||||
bool operator>(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
|
||||||
bool operator==(const SamplerState& lhs, const SamplerState& rhs);
|
|
||||||
bool operator!=(const SamplerState& lhs, const SamplerState& rhs);
|
|
||||||
bool operator>(const SamplerState& lhs, const SamplerState& rhs);
|
|
||||||
bool operator<(const SamplerState& lhs, const SamplerState& rhs);
|
|
||||||
|
|
||||||
struct ComputePipelineInfo
|
|
||||||
{
|
|
||||||
VkPipelineLayout pipeline_layout;
|
|
||||||
VkShaderModule cs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ComputePipelineInfoHash
|
|
||||||
{
|
|
||||||
std::size_t operator()(const ComputePipelineInfo& key) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
|
||||||
bool operator!=(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
|
||||||
bool operator<(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
|
||||||
bool operator>(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
|
||||||
|
|
||||||
class ObjectCache
|
class ObjectCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -103,14 +57,6 @@ public:
|
||||||
return m_utility_shader_uniform_buffer.get();
|
return m_utility_shader_uniform_buffer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get utility shader header based on current config.
|
|
||||||
std::string GetUtilityShaderHeader() const;
|
|
||||||
|
|
||||||
// Accesses ShaderGen shader caches
|
|
||||||
VkShaderModule GetVertexShaderForUid(const VertexShaderUid& uid);
|
|
||||||
VkShaderModule GetGeometryShaderForUid(const GeometryShaderUid& uid);
|
|
||||||
VkShaderModule GetPixelShaderForUid(const PixelShaderUid& uid);
|
|
||||||
|
|
||||||
// Static samplers
|
// Static samplers
|
||||||
VkSampler GetPointSampler() const { return m_point_sampler; }
|
VkSampler GetPointSampler() const { return m_point_sampler; }
|
||||||
VkSampler GetLinearSampler() const { return m_linear_sampler; }
|
VkSampler GetLinearSampler() const { return m_linear_sampler; }
|
||||||
|
@ -119,64 +65,17 @@ public:
|
||||||
// Perform at startup, create descriptor layouts, compiles all static shaders.
|
// Perform at startup, create descriptor layouts, compiles all static shaders.
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
|
||||||
// Creates a pipeline for the specified description. The resulting pipeline, if successful
|
|
||||||
// is not stored anywhere, this is left up to the caller.
|
|
||||||
VkPipeline CreatePipeline(const PipelineInfo& info);
|
|
||||||
|
|
||||||
// Find a pipeline by the specified description, if not found, attempts to create it.
|
|
||||||
VkPipeline GetPipeline(const PipelineInfo& info);
|
|
||||||
|
|
||||||
// Find a pipeline by the specified description, if not found, attempts to create it. If this
|
|
||||||
// resulted in a pipeline being created, the second field of the return value will be false,
|
|
||||||
// otherwise for a cache hit it will be true.
|
|
||||||
std::pair<VkPipeline, bool> GetPipelineWithCacheResult(const PipelineInfo& info);
|
|
||||||
|
|
||||||
// Creates a compute pipeline, and does not track the handle.
|
|
||||||
VkPipeline CreateComputePipeline(const ComputePipelineInfo& info);
|
|
||||||
|
|
||||||
// Find a pipeline by the specified description, if not found, attempts to create it
|
|
||||||
VkPipeline GetComputePipeline(const ComputePipelineInfo& info);
|
|
||||||
|
|
||||||
// Clears our pipeline cache of all objects. This is necessary when recompiling shaders,
|
|
||||||
// as drivers are free to return the same pointer again, which means that we may end up using
|
|
||||||
// and old pipeline object if they are not cleared first. Some stutter may be experienced
|
|
||||||
// while our cache is rebuilt on use, but the pipeline cache object should mitigate this.
|
|
||||||
// NOTE: Ensure that none of these objects are in use before calling.
|
|
||||||
void ClearPipelineCache();
|
|
||||||
|
|
||||||
// Saves the pipeline cache to disk. Call when shutting down.
|
|
||||||
void SavePipelineCache();
|
|
||||||
|
|
||||||
// Clear sampler cache, use when anisotropy mode changes
|
// Clear sampler cache, use when anisotropy mode changes
|
||||||
// WARNING: Ensure none of the objects from here are in use when calling
|
// WARNING: Ensure none of the objects from here are in use when calling
|
||||||
void ClearSamplerCache();
|
void ClearSamplerCache();
|
||||||
|
|
||||||
// Recompile shared shaders, call when stereo mode changes.
|
|
||||||
void RecompileSharedShaders();
|
|
||||||
|
|
||||||
// Reload pipeline cache. This will destroy all pipelines.
|
|
||||||
void ReloadShaderAndPipelineCaches();
|
|
||||||
|
|
||||||
// Shared shader accessors
|
|
||||||
VkShaderModule GetScreenQuadVertexShader() const { return m_screen_quad_vertex_shader; }
|
|
||||||
VkShaderModule GetPassthroughVertexShader() const { return m_passthrough_vertex_shader; }
|
|
||||||
VkShaderModule GetScreenQuadGeometryShader() const { return m_screen_quad_geometry_shader; }
|
|
||||||
VkShaderModule GetPassthroughGeometryShader() const { return m_passthrough_geometry_shader; }
|
|
||||||
private:
|
private:
|
||||||
bool CreatePipelineCache();
|
|
||||||
bool LoadPipelineCache();
|
|
||||||
bool ValidatePipelineCache(const u8* data, size_t data_length);
|
|
||||||
void DestroyPipelineCache();
|
|
||||||
void LoadShaderCaches();
|
|
||||||
void DestroyShaderCaches();
|
|
||||||
bool CreateDescriptorSetLayouts();
|
bool CreateDescriptorSetLayouts();
|
||||||
void DestroyDescriptorSetLayouts();
|
void DestroyDescriptorSetLayouts();
|
||||||
bool CreatePipelineLayouts();
|
bool CreatePipelineLayouts();
|
||||||
void DestroyPipelineLayouts();
|
void DestroyPipelineLayouts();
|
||||||
bool CreateUtilityShaderVertexFormat();
|
bool CreateUtilityShaderVertexFormat();
|
||||||
bool CreateStaticSamplers();
|
bool CreateStaticSamplers();
|
||||||
bool CompileSharedShaders();
|
|
||||||
void DestroySharedShaders();
|
|
||||||
void DestroySamplers();
|
void DestroySamplers();
|
||||||
|
|
||||||
std::array<VkDescriptorSetLayout, NUM_DESCRIPTOR_SET_LAYOUTS> m_descriptor_set_layouts = {};
|
std::array<VkDescriptorSetLayout, NUM_DESCRIPTOR_SET_LAYOUTS> m_descriptor_set_layouts = {};
|
||||||
|
@ -186,32 +85,10 @@ private:
|
||||||
std::unique_ptr<StreamBuffer> m_utility_shader_vertex_buffer;
|
std::unique_ptr<StreamBuffer> m_utility_shader_vertex_buffer;
|
||||||
std::unique_ptr<StreamBuffer> m_utility_shader_uniform_buffer;
|
std::unique_ptr<StreamBuffer> m_utility_shader_uniform_buffer;
|
||||||
|
|
||||||
template <typename Uid>
|
|
||||||
struct ShaderCache
|
|
||||||
{
|
|
||||||
std::map<Uid, VkShaderModule> shader_map;
|
|
||||||
LinearDiskCache<Uid, u32> disk_cache;
|
|
||||||
};
|
|
||||||
ShaderCache<VertexShaderUid> m_vs_cache;
|
|
||||||
ShaderCache<GeometryShaderUid> m_gs_cache;
|
|
||||||
ShaderCache<PixelShaderUid> m_ps_cache;
|
|
||||||
|
|
||||||
std::unordered_map<PipelineInfo, VkPipeline, PipelineInfoHash> m_pipeline_objects;
|
|
||||||
std::unordered_map<ComputePipelineInfo, VkPipeline, ComputePipelineInfoHash>
|
|
||||||
m_compute_pipeline_objects;
|
|
||||||
VkPipelineCache m_pipeline_cache = VK_NULL_HANDLE;
|
|
||||||
std::string m_pipeline_cache_filename;
|
|
||||||
|
|
||||||
VkSampler m_point_sampler = VK_NULL_HANDLE;
|
VkSampler m_point_sampler = VK_NULL_HANDLE;
|
||||||
VkSampler m_linear_sampler = VK_NULL_HANDLE;
|
VkSampler m_linear_sampler = VK_NULL_HANDLE;
|
||||||
|
|
||||||
std::map<SamplerState, VkSampler> m_sampler_cache;
|
std::map<SamplerState, VkSampler> m_sampler_cache;
|
||||||
|
|
||||||
// Utility/shared shaders
|
|
||||||
VkShaderModule m_screen_quad_vertex_shader = VK_NULL_HANDLE;
|
|
||||||
VkShaderModule m_passthrough_vertex_shader = VK_NULL_HANDLE;
|
|
||||||
VkShaderModule m_screen_quad_geometry_shader = VK_NULL_HANDLE;
|
|
||||||
VkShaderModule m_passthrough_geometry_shader = VK_NULL_HANDLE;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::unique_ptr<ObjectCache> g_object_cache;
|
extern std::unique_ptr<ObjectCache> g_object_cache;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "VideoBackends/Vulkan/CommandBufferManager.h"
|
#include "VideoBackends/Vulkan/CommandBufferManager.h"
|
||||||
#include "VideoBackends/Vulkan/ObjectCache.h"
|
#include "VideoBackends/Vulkan/ObjectCache.h"
|
||||||
|
#include "VideoBackends/Vulkan/ShaderCache.h"
|
||||||
#include "VideoBackends/Vulkan/Texture2D.h"
|
#include "VideoBackends/Vulkan/Texture2D.h"
|
||||||
#include "VideoBackends/Vulkan/Util.h"
|
#include "VideoBackends/Vulkan/Util.h"
|
||||||
#include "VideoBackends/Vulkan/VulkanContext.h"
|
#include "VideoBackends/Vulkan/VulkanContext.h"
|
||||||
|
@ -43,12 +44,12 @@ void VulkanPostProcessing::BlitFromTexture(const TargetRectangle& dst, const Tar
|
||||||
{
|
{
|
||||||
// If the source layer is negative we simply copy all available layers.
|
// If the source layer is negative we simply copy all available layers.
|
||||||
VkShaderModule geometry_shader =
|
VkShaderModule geometry_shader =
|
||||||
src_layer < 0 ? g_object_cache->GetPassthroughGeometryShader() : VK_NULL_HANDLE;
|
src_layer < 0 ? g_shader_cache->GetPassthroughGeometryShader() : VK_NULL_HANDLE;
|
||||||
VkShaderModule fragment_shader =
|
VkShaderModule fragment_shader =
|
||||||
m_fragment_shader != VK_NULL_HANDLE ? m_fragment_shader : m_default_fragment_shader;
|
m_fragment_shader != VK_NULL_HANDLE ? m_fragment_shader : m_default_fragment_shader;
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD), render_pass,
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD), render_pass,
|
||||||
g_object_cache->GetPassthroughVertexShader(), geometry_shader,
|
g_shader_cache->GetPassthroughVertexShader(), geometry_shader,
|
||||||
fragment_shader);
|
fragment_shader);
|
||||||
|
|
||||||
// Source is always bound.
|
// Source is always bound.
|
||||||
|
@ -240,7 +241,7 @@ bool VulkanPostProcessing::RecompileShader()
|
||||||
if (m_fragment_shader != VK_NULL_HANDLE)
|
if (m_fragment_shader != VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
g_command_buffer_mgr->WaitForGPUIdle();
|
g_command_buffer_mgr->WaitForGPUIdle();
|
||||||
g_object_cache->ClearPipelineCache();
|
g_shader_cache->ClearPipelineCache();
|
||||||
vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_fragment_shader, nullptr);
|
vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_fragment_shader, nullptr);
|
||||||
m_fragment_shader = VK_NULL_HANDLE;
|
m_fragment_shader = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,8 +462,8 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||||
FramebufferManager::GetInstance()->GetEFBLoadRenderPass(),
|
FramebufferManager::GetInstance()->GetEFBLoadRenderPass(),
|
||||||
g_object_cache->GetPassthroughVertexShader(),
|
g_shader_cache->GetPassthroughVertexShader(),
|
||||||
g_object_cache->GetPassthroughGeometryShader(), m_clear_fragment_shader);
|
g_shader_cache->GetPassthroughGeometryShader(), m_clear_fragment_shader);
|
||||||
|
|
||||||
draw.SetRasterizationState(rs_state);
|
draw.SetRasterizationState(rs_state);
|
||||||
draw.SetDepthStencilState(depth_state);
|
draw.SetDepthStencilState(depth_state);
|
||||||
|
@ -1168,8 +1168,8 @@ void Renderer::CheckForConfigChanges()
|
||||||
BindEFBToStateTracker();
|
BindEFBToStateTracker();
|
||||||
RecompileShaders();
|
RecompileShaders();
|
||||||
FramebufferManager::GetInstance()->RecompileShaders();
|
FramebufferManager::GetInstance()->RecompileShaders();
|
||||||
g_object_cache->ReloadShaderAndPipelineCaches();
|
g_shader_cache->ReloadShaderAndPipelineCaches();
|
||||||
g_object_cache->RecompileSharedShaders();
|
g_shader_cache->RecompileSharedShaders();
|
||||||
StateTracker::GetInstance()->InvalidateShaderPointers();
|
StateTracker::GetInstance()->InvalidateShaderPointers();
|
||||||
StateTracker::GetInstance()->ReloadPipelineUIDCache();
|
StateTracker::GetInstance()->ReloadPipelineUIDCache();
|
||||||
}
|
}
|
||||||
|
@ -1500,7 +1500,7 @@ bool Renderer::CompileShaders()
|
||||||
|
|
||||||
)";
|
)";
|
||||||
|
|
||||||
std::string source = g_object_cache->GetUtilityShaderHeader() + CLEAR_FRAGMENT_SHADER_SOURCE;
|
std::string source = g_shader_cache->GetUtilityShaderHeader() + CLEAR_FRAGMENT_SHADER_SOURCE;
|
||||||
m_clear_fragment_shader = Util::CompileAndCreateFragmentShader(source);
|
m_clear_fragment_shader = Util::CompileAndCreateFragmentShader(source);
|
||||||
|
|
||||||
return m_clear_fragment_shader != VK_NULL_HANDLE;
|
return m_clear_fragment_shader != VK_NULL_HANDLE;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,172 @@
|
||||||
|
// Copyright 2016 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/LinearDiskCache.h"
|
||||||
|
|
||||||
|
#include "VideoBackends/Vulkan/Constants.h"
|
||||||
|
#include "VideoBackends/Vulkan/ObjectCache.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/GeometryShaderGen.h"
|
||||||
|
#include "VideoCommon/PixelShaderGen.h"
|
||||||
|
#include "VideoCommon/RenderState.h"
|
||||||
|
#include "VideoCommon/VertexShaderGen.h"
|
||||||
|
|
||||||
|
namespace Vulkan
|
||||||
|
{
|
||||||
|
class CommandBufferManager;
|
||||||
|
class VertexFormat;
|
||||||
|
class StreamBuffer;
|
||||||
|
|
||||||
|
class CommandBufferManager;
|
||||||
|
class VertexFormat;
|
||||||
|
class StreamBuffer;
|
||||||
|
|
||||||
|
struct PipelineInfo
|
||||||
|
{
|
||||||
|
// These are packed in descending order of size, to avoid any padding so that the structure
|
||||||
|
// can be copied/compared as a single block of memory. 64-bit pointer size is assumed.
|
||||||
|
const VertexFormat* vertex_format;
|
||||||
|
VkPipelineLayout pipeline_layout;
|
||||||
|
VkShaderModule vs;
|
||||||
|
VkShaderModule gs;
|
||||||
|
VkShaderModule ps;
|
||||||
|
VkRenderPass render_pass;
|
||||||
|
BlendingState blend_state;
|
||||||
|
RasterizationState rasterization_state;
|
||||||
|
DepthStencilState depth_stencil_state;
|
||||||
|
VkPrimitiveTopology primitive_topology;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PipelineInfoHash
|
||||||
|
{
|
||||||
|
std::size_t operator()(const PipelineInfo& key) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||||
|
bool operator!=(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||||
|
bool operator<(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||||
|
bool operator>(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||||
|
bool operator==(const SamplerState& lhs, const SamplerState& rhs);
|
||||||
|
bool operator!=(const SamplerState& lhs, const SamplerState& rhs);
|
||||||
|
bool operator>(const SamplerState& lhs, const SamplerState& rhs);
|
||||||
|
bool operator<(const SamplerState& lhs, const SamplerState& rhs);
|
||||||
|
|
||||||
|
struct ComputePipelineInfo
|
||||||
|
{
|
||||||
|
VkPipelineLayout pipeline_layout;
|
||||||
|
VkShaderModule cs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ComputePipelineInfoHash
|
||||||
|
{
|
||||||
|
std::size_t operator()(const ComputePipelineInfo& key) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
||||||
|
bool operator!=(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
||||||
|
bool operator<(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
||||||
|
bool operator>(const ComputePipelineInfo& lhs, const ComputePipelineInfo& rhs);
|
||||||
|
|
||||||
|
class ShaderCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShaderCache();
|
||||||
|
~ShaderCache();
|
||||||
|
|
||||||
|
// Get utility shader header based on current config.
|
||||||
|
std::string GetUtilityShaderHeader() const;
|
||||||
|
|
||||||
|
// Accesses ShaderGen shader caches
|
||||||
|
VkShaderModule GetVertexShaderForUid(const VertexShaderUid& uid);
|
||||||
|
VkShaderModule GetGeometryShaderForUid(const GeometryShaderUid& uid);
|
||||||
|
VkShaderModule GetPixelShaderForUid(const PixelShaderUid& uid);
|
||||||
|
|
||||||
|
// Perform at startup, create descriptor layouts, compiles all static shaders.
|
||||||
|
bool Initialize();
|
||||||
|
|
||||||
|
// Creates a pipeline for the specified description. The resulting pipeline, if successful
|
||||||
|
// is not stored anywhere, this is left up to the caller.
|
||||||
|
VkPipeline CreatePipeline(const PipelineInfo& info);
|
||||||
|
|
||||||
|
// Find a pipeline by the specified description, if not found, attempts to create it.
|
||||||
|
VkPipeline GetPipeline(const PipelineInfo& info);
|
||||||
|
|
||||||
|
// Find a pipeline by the specified description, if not found, attempts to create it. If this
|
||||||
|
// resulted in a pipeline being created, the second field of the return value will be false,
|
||||||
|
// otherwise for a cache hit it will be true.
|
||||||
|
std::pair<VkPipeline, bool> GetPipelineWithCacheResult(const PipelineInfo& info);
|
||||||
|
|
||||||
|
// Creates a compute pipeline, and does not track the handle.
|
||||||
|
VkPipeline CreateComputePipeline(const ComputePipelineInfo& info);
|
||||||
|
|
||||||
|
// Find a pipeline by the specified description, if not found, attempts to create it
|
||||||
|
VkPipeline GetComputePipeline(const ComputePipelineInfo& info);
|
||||||
|
|
||||||
|
// Clears our pipeline cache of all objects. This is necessary when recompiling shaders,
|
||||||
|
// as drivers are free to return the same pointer again, which means that we may end up using
|
||||||
|
// and old pipeline object if they are not cleared first. Some stutter may be experienced
|
||||||
|
// while our cache is rebuilt on use, but the pipeline cache object should mitigate this.
|
||||||
|
// NOTE: Ensure that none of these objects are in use before calling.
|
||||||
|
void ClearPipelineCache();
|
||||||
|
|
||||||
|
// Saves the pipeline cache to disk. Call when shutting down.
|
||||||
|
void SavePipelineCache();
|
||||||
|
|
||||||
|
// Recompile shared shaders, call when stereo mode changes.
|
||||||
|
void RecompileSharedShaders();
|
||||||
|
|
||||||
|
// Reload pipeline cache. This will destroy all pipelines.
|
||||||
|
void ReloadShaderAndPipelineCaches();
|
||||||
|
|
||||||
|
// Shared shader accessors
|
||||||
|
VkShaderModule GetScreenQuadVertexShader() const { return m_screen_quad_vertex_shader; }
|
||||||
|
VkShaderModule GetPassthroughVertexShader() const { return m_passthrough_vertex_shader; }
|
||||||
|
VkShaderModule GetScreenQuadGeometryShader() const { return m_screen_quad_geometry_shader; }
|
||||||
|
VkShaderModule GetPassthroughGeometryShader() const { return m_passthrough_geometry_shader; }
|
||||||
|
private:
|
||||||
|
bool CreatePipelineCache();
|
||||||
|
bool LoadPipelineCache();
|
||||||
|
bool ValidatePipelineCache(const u8* data, size_t data_length);
|
||||||
|
void DestroyPipelineCache();
|
||||||
|
void LoadShaderCaches();
|
||||||
|
void DestroyShaderCaches();
|
||||||
|
bool CompileSharedShaders();
|
||||||
|
void DestroySharedShaders();
|
||||||
|
|
||||||
|
template <typename Uid>
|
||||||
|
struct ShaderModuleCache
|
||||||
|
{
|
||||||
|
std::map<Uid, VkShaderModule> shader_map;
|
||||||
|
LinearDiskCache<Uid, u32> disk_cache;
|
||||||
|
};
|
||||||
|
ShaderModuleCache<VertexShaderUid> m_vs_cache;
|
||||||
|
ShaderModuleCache<GeometryShaderUid> m_gs_cache;
|
||||||
|
ShaderModuleCache<PixelShaderUid> m_ps_cache;
|
||||||
|
|
||||||
|
std::unordered_map<PipelineInfo, VkPipeline, PipelineInfoHash> m_pipeline_objects;
|
||||||
|
std::unordered_map<ComputePipelineInfo, VkPipeline, ComputePipelineInfoHash>
|
||||||
|
m_compute_pipeline_objects;
|
||||||
|
VkPipelineCache m_pipeline_cache = VK_NULL_HANDLE;
|
||||||
|
std::string m_pipeline_cache_filename;
|
||||||
|
|
||||||
|
// Utility/shared shaders
|
||||||
|
VkShaderModule m_screen_quad_vertex_shader = VK_NULL_HANDLE;
|
||||||
|
VkShaderModule m_passthrough_vertex_shader = VK_NULL_HANDLE;
|
||||||
|
VkShaderModule m_screen_quad_geometry_shader = VK_NULL_HANDLE;
|
||||||
|
VkShaderModule m_passthrough_geometry_shader = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::unique_ptr<ShaderCache> g_shader_cache;
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
|
@ -13,6 +13,7 @@
|
||||||
#include "VideoBackends/Vulkan/Constants.h"
|
#include "VideoBackends/Vulkan/Constants.h"
|
||||||
#include "VideoBackends/Vulkan/FramebufferManager.h"
|
#include "VideoBackends/Vulkan/FramebufferManager.h"
|
||||||
#include "VideoBackends/Vulkan/ObjectCache.h"
|
#include "VideoBackends/Vulkan/ObjectCache.h"
|
||||||
|
#include "VideoBackends/Vulkan/ShaderCache.h"
|
||||||
#include "VideoBackends/Vulkan/StreamBuffer.h"
|
#include "VideoBackends/Vulkan/StreamBuffer.h"
|
||||||
#include "VideoBackends/Vulkan/Util.h"
|
#include "VideoBackends/Vulkan/Util.h"
|
||||||
#include "VideoBackends/Vulkan/VertexFormat.h"
|
#include "VideoBackends/Vulkan/VertexFormat.h"
|
||||||
|
@ -181,7 +182,7 @@ bool StateTracker::PrecachePipelineUID(const SerializedPipelineUID& uid)
|
||||||
pinfo.pipeline_layout = uid.ps_uid.GetUidData()->bounding_box ?
|
pinfo.pipeline_layout = uid.ps_uid.GetUidData()->bounding_box ?
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_BBOX) :
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_BBOX) :
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD);
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD);
|
||||||
pinfo.vs = g_object_cache->GetVertexShaderForUid(uid.vs_uid);
|
pinfo.vs = g_shader_cache->GetVertexShaderForUid(uid.vs_uid);
|
||||||
if (pinfo.vs == VK_NULL_HANDLE)
|
if (pinfo.vs == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Failed to get vertex shader from cached UID.");
|
WARN_LOG(VIDEO, "Failed to get vertex shader from cached UID.");
|
||||||
|
@ -189,14 +190,14 @@ bool StateTracker::PrecachePipelineUID(const SerializedPipelineUID& uid)
|
||||||
}
|
}
|
||||||
if (g_vulkan_context->SupportsGeometryShaders() && !uid.gs_uid.GetUidData()->IsPassthrough())
|
if (g_vulkan_context->SupportsGeometryShaders() && !uid.gs_uid.GetUidData()->IsPassthrough())
|
||||||
{
|
{
|
||||||
pinfo.gs = g_object_cache->GetGeometryShaderForUid(uid.gs_uid);
|
pinfo.gs = g_shader_cache->GetGeometryShaderForUid(uid.gs_uid);
|
||||||
if (pinfo.gs == VK_NULL_HANDLE)
|
if (pinfo.gs == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Failed to get geometry shader from cached UID.");
|
WARN_LOG(VIDEO, "Failed to get geometry shader from cached UID.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pinfo.ps = g_object_cache->GetPixelShaderForUid(uid.ps_uid);
|
pinfo.ps = g_shader_cache->GetPixelShaderForUid(uid.ps_uid);
|
||||||
if (pinfo.ps == VK_NULL_HANDLE)
|
if (pinfo.ps == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Failed to get pixel shader from cached UID.");
|
WARN_LOG(VIDEO, "Failed to get pixel shader from cached UID.");
|
||||||
|
@ -208,7 +209,7 @@ bool StateTracker::PrecachePipelineUID(const SerializedPipelineUID& uid)
|
||||||
pinfo.blend_state.hex = uid.blend_state_bits;
|
pinfo.blend_state.hex = uid.blend_state_bits;
|
||||||
pinfo.primitive_topology = uid.primitive_topology;
|
pinfo.primitive_topology = uid.primitive_topology;
|
||||||
|
|
||||||
VkPipeline pipeline = g_object_cache->GetPipeline(pinfo);
|
VkPipeline pipeline = g_shader_cache->GetPipeline(pinfo);
|
||||||
if (pipeline == VK_NULL_HANDLE)
|
if (pipeline == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Failed to get pipeline from cached UID.");
|
WARN_LOG(VIDEO, "Failed to get pipeline from cached UID.");
|
||||||
|
@ -327,7 +328,7 @@ bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type)
|
||||||
|
|
||||||
if (vs_uid != m_vs_uid)
|
if (vs_uid != m_vs_uid)
|
||||||
{
|
{
|
||||||
m_pipeline_state.vs = g_object_cache->GetVertexShaderForUid(vs_uid);
|
m_pipeline_state.vs = g_shader_cache->GetVertexShaderForUid(vs_uid);
|
||||||
m_vs_uid = vs_uid;
|
m_vs_uid = vs_uid;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -340,7 +341,7 @@ bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type)
|
||||||
if (gs_uid.GetUidData()->IsPassthrough())
|
if (gs_uid.GetUidData()->IsPassthrough())
|
||||||
m_pipeline_state.gs = VK_NULL_HANDLE;
|
m_pipeline_state.gs = VK_NULL_HANDLE;
|
||||||
else
|
else
|
||||||
m_pipeline_state.gs = g_object_cache->GetGeometryShaderForUid(gs_uid);
|
m_pipeline_state.gs = g_shader_cache->GetGeometryShaderForUid(gs_uid);
|
||||||
|
|
||||||
m_gs_uid = gs_uid;
|
m_gs_uid = gs_uid;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -349,7 +350,7 @@ bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type)
|
||||||
|
|
||||||
if (ps_uid != m_ps_uid)
|
if (ps_uid != m_ps_uid)
|
||||||
{
|
{
|
||||||
m_pipeline_state.ps = g_object_cache->GetPixelShaderForUid(ps_uid);
|
m_pipeline_state.ps = g_shader_cache->GetPixelShaderForUid(ps_uid);
|
||||||
m_ps_uid = ps_uid;
|
m_ps_uid = ps_uid;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -887,7 +888,7 @@ void StateTracker::EndClearRenderPass()
|
||||||
|
|
||||||
VkPipeline StateTracker::GetPipelineAndCacheUID(const PipelineInfo& info)
|
VkPipeline StateTracker::GetPipelineAndCacheUID(const PipelineInfo& info)
|
||||||
{
|
{
|
||||||
auto result = g_object_cache->GetPipelineWithCacheResult(info);
|
auto result = g_shader_cache->GetPipelineWithCacheResult(info);
|
||||||
|
|
||||||
// Add to the UID cache if it is a new pipeline.
|
// Add to the UID cache if it is a new pipeline.
|
||||||
if (!result.second && g_ActiveConfig.bShaderCache)
|
if (!result.second && g_ActiveConfig.bShaderCache)
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/LinearDiskCache.h"
|
#include "Common/LinearDiskCache.h"
|
||||||
#include "VideoBackends/Vulkan/Constants.h"
|
#include "VideoBackends/Vulkan/Constants.h"
|
||||||
#include "VideoBackends/Vulkan/ObjectCache.h"
|
#include "VideoBackends/Vulkan/ShaderCache.h"
|
||||||
#include "VideoCommon/GeometryShaderGen.h"
|
#include "VideoCommon/GeometryShaderGen.h"
|
||||||
#include "VideoCommon/NativeVertexFormat.h"
|
#include "VideoCommon/NativeVertexFormat.h"
|
||||||
#include "VideoCommon/PixelShaderGen.h"
|
#include "VideoCommon/PixelShaderGen.h"
|
||||||
|
|
|
@ -299,7 +299,7 @@ bool TextureCache::CompileShaders()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
std::string header = g_object_cache->GetUtilityShaderHeader();
|
std::string header = g_shader_cache->GetUtilityShaderHeader();
|
||||||
std::string source;
|
std::string source;
|
||||||
|
|
||||||
source = header + COPY_SHADER_SOURCE;
|
source = header + COPY_SHADER_SOURCE;
|
||||||
|
@ -385,8 +385,8 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
|
||||||
|
|
||||||
UtilityShaderDraw draw(command_buffer,
|
UtilityShaderDraw draw(command_buffer,
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
|
||||||
m_render_pass, g_object_cache->GetPassthroughVertexShader(),
|
m_render_pass, g_shader_cache->GetPassthroughVertexShader(),
|
||||||
g_object_cache->GetPassthroughGeometryShader(),
|
g_shader_cache->GetPassthroughGeometryShader(),
|
||||||
is_depth_copy ? m_efb_depth_to_tex_shader : m_efb_color_to_tex_shader);
|
is_depth_copy ? m_efb_depth_to_tex_shader : m_efb_color_to_tex_shader);
|
||||||
|
|
||||||
draw.SetPushConstants(colmat, (is_depth_copy ? sizeof(float) * 20 : sizeof(float) * 28));
|
draw.SetPushConstants(colmat, (is_depth_copy ? sizeof(float) * 20 : sizeof(float) * 28));
|
||||||
|
|
|
@ -200,7 +200,7 @@ void TextureConverter::ConvertTexture(TextureCacheBase::TCacheEntry* dst_entry,
|
||||||
// Bind and draw to the destination.
|
// Bind and draw to the destination.
|
||||||
UtilityShaderDraw draw(command_buffer,
|
UtilityShaderDraw draw(command_buffer,
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_TEXTURE_CONVERSION),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_TEXTURE_CONVERSION),
|
||||||
render_pass, g_object_cache->GetScreenQuadVertexShader(), VK_NULL_HANDLE,
|
render_pass, g_shader_cache->GetScreenQuadVertexShader(), VK_NULL_HANDLE,
|
||||||
m_palette_conversion_shaders[palette_format]);
|
m_palette_conversion_shaders[palette_format]);
|
||||||
|
|
||||||
VkRect2D region = {{0, 0}, {dst_entry->GetWidth(), dst_entry->GetHeight()}};
|
VkRect2D region = {{0, 0}, {dst_entry->GetWidth(), dst_entry->GetHeight()}};
|
||||||
|
@ -240,7 +240,7 @@ void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_p
|
||||||
|
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
|
||||||
m_encoding_render_pass, g_object_cache->GetScreenQuadVertexShader(),
|
m_encoding_render_pass, g_shader_cache->GetScreenQuadVertexShader(),
|
||||||
VK_NULL_HANDLE, shader);
|
VK_NULL_HANDLE, shader);
|
||||||
|
|
||||||
// Uniform - int4 of left,top,native_width,scale
|
// Uniform - int4 of left,top,native_width,scale
|
||||||
|
@ -299,7 +299,7 @@ void TextureConverter::EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u
|
||||||
u32 output_width = dst_width / 2;
|
u32 output_width = dst_width / 2;
|
||||||
UtilityShaderDraw draw(command_buffer,
|
UtilityShaderDraw draw(command_buffer,
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||||
m_encoding_render_pass, g_object_cache->GetPassthroughVertexShader(),
|
m_encoding_render_pass, g_shader_cache->GetPassthroughVertexShader(),
|
||||||
VK_NULL_HANDLE, m_rgb_to_yuyv_shader);
|
VK_NULL_HANDLE, m_rgb_to_yuyv_shader);
|
||||||
VkRect2D region = {{0, 0}, {output_width, dst_height}};
|
VkRect2D region = {{0, 0}, {output_width, dst_height}};
|
||||||
draw.BeginRenderPass(m_encoding_render_framebuffer, region);
|
draw.BeginRenderPass(m_encoding_render_framebuffer, region);
|
||||||
|
@ -376,7 +376,7 @@ void TextureConverter::DecodeYUYVTextureFromMemory(VKTexture* dst_texture, const
|
||||||
// Convert from the YUYV data now in the intermediate texture to RGBA in the destination.
|
// Convert from the YUYV data now in the intermediate texture to RGBA in the destination.
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_TEXTURE_CONVERSION),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_TEXTURE_CONVERSION),
|
||||||
m_encoding_render_pass, g_object_cache->GetScreenQuadVertexShader(),
|
m_encoding_render_pass, g_shader_cache->GetScreenQuadVertexShader(),
|
||||||
VK_NULL_HANDLE, m_yuyv_to_rgb_shader);
|
VK_NULL_HANDLE, m_yuyv_to_rgb_shader);
|
||||||
VkRect2D region = {{0, 0}, {src_width, src_height}};
|
VkRect2D region = {{0, 0}, {src_width, src_height}};
|
||||||
draw.BeginRenderPass(dst_texture->GetFramebuffer(), region);
|
draw.BeginRenderPass(dst_texture->GetFramebuffer(), region);
|
||||||
|
@ -838,7 +838,7 @@ bool TextureConverter::CompileYUYVConversionShaders()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
std::string header = g_object_cache->GetUtilityShaderHeader();
|
std::string header = g_shader_cache->GetUtilityShaderHeader();
|
||||||
std::string source = header + RGB_TO_YUYV_SHADER_SOURCE;
|
std::string source = header + RGB_TO_YUYV_SHADER_SOURCE;
|
||||||
m_rgb_to_yuyv_shader = Util::CompileAndCreateFragmentShader(source);
|
m_rgb_to_yuyv_shader = Util::CompileAndCreateFragmentShader(source);
|
||||||
source = header + YUYV_TO_RGB_SHADER_SOURCE;
|
source = header + YUYV_TO_RGB_SHADER_SOURCE;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "VideoBackends/Vulkan/CommandBufferManager.h"
|
#include "VideoBackends/Vulkan/CommandBufferManager.h"
|
||||||
#include "VideoBackends/Vulkan/ObjectCache.h"
|
#include "VideoBackends/Vulkan/ObjectCache.h"
|
||||||
|
#include "VideoBackends/Vulkan/ShaderCache.h"
|
||||||
#include "VideoBackends/Vulkan/ShaderCompiler.h"
|
#include "VideoBackends/Vulkan/ShaderCompiler.h"
|
||||||
#include "VideoBackends/Vulkan/StateTracker.h"
|
#include "VideoBackends/Vulkan/StateTracker.h"
|
||||||
#include "VideoBackends/Vulkan/StreamBuffer.h"
|
#include "VideoBackends/Vulkan/StreamBuffer.h"
|
||||||
|
@ -720,7 +721,7 @@ void UtilityShaderDraw::BindDescriptors()
|
||||||
|
|
||||||
bool UtilityShaderDraw::BindPipeline()
|
bool UtilityShaderDraw::BindPipeline()
|
||||||
{
|
{
|
||||||
VkPipeline pipeline = g_object_cache->GetPipeline(m_pipeline_info);
|
VkPipeline pipeline = g_shader_cache->GetPipeline(m_pipeline_info);
|
||||||
if (pipeline == VK_NULL_HANDLE)
|
if (pipeline == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to get pipeline for backend shader draw");
|
PanicAlert("Failed to get pipeline for backend shader draw");
|
||||||
|
@ -873,7 +874,7 @@ void ComputeShaderDispatcher::BindDescriptors()
|
||||||
|
|
||||||
bool ComputeShaderDispatcher::BindPipeline()
|
bool ComputeShaderDispatcher::BindPipeline()
|
||||||
{
|
{
|
||||||
VkPipeline pipeline = g_object_cache->GetComputePipeline(m_pipeline_info);
|
VkPipeline pipeline = g_shader_cache->GetComputePipeline(m_pipeline_info);
|
||||||
if (pipeline == VK_NULL_HANDLE)
|
if (pipeline == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to get pipeline for backend compute dispatch");
|
PanicAlert("Failed to get pipeline for backend compute dispatch");
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "VideoBackends/Vulkan/Constants.h"
|
#include "VideoBackends/Vulkan/Constants.h"
|
||||||
#include "VideoBackends/Vulkan/ObjectCache.h"
|
#include "VideoBackends/Vulkan/ObjectCache.h"
|
||||||
|
#include "VideoBackends/Vulkan/ShaderCache.h"
|
||||||
#include "VideoCommon/RenderState.h"
|
#include "VideoCommon/RenderState.h"
|
||||||
#include "VideoCommon/TextureConfig.h"
|
#include "VideoCommon/TextureConfig.h"
|
||||||
|
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
{
|
{
|
||||||
class CommandBufferManager;
|
class CommandBufferManager;
|
||||||
class ObjectCache;
|
|
||||||
class StateTracker;
|
class StateTracker;
|
||||||
|
|
||||||
namespace Util
|
namespace Util
|
||||||
|
|
|
@ -225,8 +225,8 @@ void VKTexture::ScaleTextureRectangle(const MathUtil::Rectangle<int>& dst_rect,
|
||||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD),
|
||||||
TextureCache::GetInstance()->GetTextureCopyRenderPass(),
|
TextureCache::GetInstance()->GetTextureCopyRenderPass(),
|
||||||
g_object_cache->GetPassthroughVertexShader(),
|
g_shader_cache->GetPassthroughVertexShader(),
|
||||||
g_object_cache->GetPassthroughGeometryShader(),
|
g_shader_cache->GetPassthroughGeometryShader(),
|
||||||
TextureCache::GetInstance()->GetCopyShader());
|
TextureCache::GetInstance()->GetCopyShader());
|
||||||
|
|
||||||
VkRect2D region = {
|
VkRect2D region = {
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
<ClCompile Include="FramebufferManager.cpp" />
|
<ClCompile Include="FramebufferManager.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="PostProcessing.cpp" />
|
<ClCompile Include="PostProcessing.cpp" />
|
||||||
|
<ClCompile Include="ShaderCache.cpp" />
|
||||||
<ClCompile Include="TextureConverter.cpp" />
|
<ClCompile Include="TextureConverter.cpp" />
|
||||||
<ClCompile Include="PerfQuery.cpp" />
|
<ClCompile Include="PerfQuery.cpp" />
|
||||||
<ClCompile Include="RasterFont.cpp" />
|
<ClCompile Include="RasterFont.cpp" />
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
<ClInclude Include="FramebufferManager.h" />
|
<ClInclude Include="FramebufferManager.h" />
|
||||||
<ClInclude Include="Constants.h" />
|
<ClInclude Include="Constants.h" />
|
||||||
<ClInclude Include="PostProcessing.h" />
|
<ClInclude Include="PostProcessing.h" />
|
||||||
|
<ClInclude Include="ShaderCache.h" />
|
||||||
<ClInclude Include="TextureConverter.h" />
|
<ClInclude Include="TextureConverter.h" />
|
||||||
<ClInclude Include="RasterFont.h" />
|
<ClInclude Include="RasterFont.h" />
|
||||||
<ClInclude Include="StagingBuffer.h" />
|
<ClInclude Include="StagingBuffer.h" />
|
||||||
|
|
|
@ -215,19 +215,22 @@ bool VideoBackend::Initialize(void* window_handle)
|
||||||
|
|
||||||
// Create main wrapper instances.
|
// Create main wrapper instances.
|
||||||
g_object_cache = std::make_unique<ObjectCache>();
|
g_object_cache = std::make_unique<ObjectCache>();
|
||||||
|
g_shader_cache = std::make_unique<ShaderCache>();
|
||||||
g_framebuffer_manager = std::make_unique<FramebufferManager>();
|
g_framebuffer_manager = std::make_unique<FramebufferManager>();
|
||||||
g_renderer = std::make_unique<Renderer>(std::move(swap_chain));
|
g_renderer = std::make_unique<Renderer>(std::move(swap_chain));
|
||||||
|
|
||||||
// Invoke init methods on main wrapper classes.
|
// Invoke init methods on main wrapper classes.
|
||||||
// These have to be done before the others because the destructors
|
// These have to be done before the others because the destructors
|
||||||
// for the remaining classes may call methods on these.
|
// for the remaining classes may call methods on these.
|
||||||
if (!g_object_cache->Initialize() || !FramebufferManager::GetInstance()->Initialize() ||
|
if (!g_object_cache->Initialize() || !g_shader_cache->Initialize() ||
|
||||||
!StateTracker::CreateInstance() || !Renderer::GetInstance()->Initialize())
|
!FramebufferManager::GetInstance()->Initialize() || !StateTracker::CreateInstance() ||
|
||||||
|
!Renderer::GetInstance()->Initialize())
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to initialize Vulkan classes.");
|
PanicAlert("Failed to initialize Vulkan classes.");
|
||||||
g_renderer.reset();
|
g_renderer.reset();
|
||||||
StateTracker::DestroyInstance();
|
StateTracker::DestroyInstance();
|
||||||
g_framebuffer_manager.reset();
|
g_framebuffer_manager.reset();
|
||||||
|
g_shader_cache.reset();
|
||||||
g_object_cache.reset();
|
g_object_cache.reset();
|
||||||
g_command_buffer_mgr.reset();
|
g_command_buffer_mgr.reset();
|
||||||
g_vulkan_context.reset();
|
g_vulkan_context.reset();
|
||||||
|
@ -250,6 +253,7 @@ bool VideoBackend::Initialize(void* window_handle)
|
||||||
g_renderer.reset();
|
g_renderer.reset();
|
||||||
StateTracker::DestroyInstance();
|
StateTracker::DestroyInstance();
|
||||||
g_framebuffer_manager.reset();
|
g_framebuffer_manager.reset();
|
||||||
|
g_shader_cache.reset();
|
||||||
g_object_cache.reset();
|
g_object_cache.reset();
|
||||||
g_command_buffer_mgr.reset();
|
g_command_buffer_mgr.reset();
|
||||||
g_vulkan_context.reset();
|
g_vulkan_context.reset();
|
||||||
|
@ -276,6 +280,7 @@ void VideoBackend::Shutdown()
|
||||||
{
|
{
|
||||||
g_command_buffer_mgr->WaitForGPUIdle();
|
g_command_buffer_mgr->WaitForGPUIdle();
|
||||||
|
|
||||||
|
g_shader_cache.reset();
|
||||||
g_object_cache.reset();
|
g_object_cache.reset();
|
||||||
g_command_buffer_mgr.reset();
|
g_command_buffer_mgr.reset();
|
||||||
g_vulkan_context.reset();
|
g_vulkan_context.reset();
|
||||||
|
@ -291,7 +296,7 @@ void VideoBackend::Video_Cleanup()
|
||||||
|
|
||||||
// Save all cached pipelines out to disk for next time.
|
// Save all cached pipelines out to disk for next time.
|
||||||
if (g_ActiveConfig.bShaderCache)
|
if (g_ActiveConfig.bShaderCache)
|
||||||
g_object_cache->SavePipelineCache();
|
g_shader_cache->SavePipelineCache();
|
||||||
|
|
||||||
g_perf_query.reset();
|
g_perf_query.reset();
|
||||||
g_texture_cache.reset();
|
g_texture_cache.reset();
|
||||||
|
|
Loading…
Reference in New Issue