2020-12-05 13:08:24 +01:00
|
|
|
#pragma once
|
2016-02-21 16:50:49 +01:00
|
|
|
#include "VKVertexProgram.h"
|
|
|
|
|
#include "VKFragmentProgram.h"
|
2019-05-24 15:31:46 +02:00
|
|
|
#include "VKRenderPass.h"
|
2020-10-27 21:41:20 +01:00
|
|
|
#include "VKPipelineCompiler.h"
|
2021-05-12 23:56:01 +02:00
|
|
|
#include "../Program/ProgramStateCache.h"
|
2016-03-20 02:26:51 +01:00
|
|
|
|
2021-03-08 21:41:23 +01:00
|
|
|
#include "util/fnv_hash.hpp"
|
|
|
|
|
|
2016-03-20 02:26:51 +01:00
|
|
|
namespace vk
|
|
|
|
|
{
|
2020-10-27 21:41:20 +01:00
|
|
|
struct VKTraits
|
2016-03-20 02:26:51 +01:00
|
|
|
{
|
2020-10-27 21:41:20 +01:00
|
|
|
using vertex_program_type = VKVertexProgram;
|
|
|
|
|
using fragment_program_type = VKFragmentProgram;
|
|
|
|
|
using pipeline_type = vk::glsl::program;
|
|
|
|
|
using pipeline_storage_type = std::unique_ptr<vk::glsl::program>;
|
|
|
|
|
using pipeline_properties = vk::pipeline_props;
|
|
|
|
|
|
|
|
|
|
static
|
2020-12-18 08:39:54 +01:00
|
|
|
void recompile_fragment_program(const RSXFragmentProgram& RSXFP, fragment_program_type& fragmentProgramData, usz ID)
|
2016-03-20 02:26:51 +01:00
|
|
|
{
|
2020-10-27 21:41:20 +01:00
|
|
|
fragmentProgramData.Decompile(RSXFP);
|
|
|
|
|
fragmentProgramData.id = static_cast<u32>(ID);
|
|
|
|
|
fragmentProgramData.Compile();
|
|
|
|
|
}
|
2017-08-04 23:11:14 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
static
|
2020-12-18 08:39:54 +01:00
|
|
|
void recompile_vertex_program(const RSXVertexProgram& RSXVP, vertex_program_type& vertexProgramData, usz ID)
|
2020-10-27 21:41:20 +01:00
|
|
|
{
|
|
|
|
|
vertexProgramData.Decompile(RSXVP);
|
|
|
|
|
vertexProgramData.id = static_cast<u32>(ID);
|
|
|
|
|
vertexProgramData.Compile();
|
|
|
|
|
}
|
2017-08-04 23:11:14 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
static
|
|
|
|
|
void validate_pipeline_properties(const VKVertexProgram&, const VKFragmentProgram& fp, vk::pipeline_props& properties)
|
|
|
|
|
{
|
|
|
|
|
//Explicitly disable writing to undefined registers
|
|
|
|
|
properties.state.att_state[0].colorWriteMask &= fp.output_color_masks[0];
|
|
|
|
|
properties.state.att_state[1].colorWriteMask &= fp.output_color_masks[1];
|
|
|
|
|
properties.state.att_state[2].colorWriteMask &= fp.output_color_masks[2];
|
|
|
|
|
properties.state.att_state[3].colorWriteMask &= fp.output_color_masks[3];
|
|
|
|
|
}
|
2016-07-17 18:57:50 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
static
|
|
|
|
|
pipeline_type* build_pipeline(
|
|
|
|
|
const vertex_program_type& vertexProgramData,
|
|
|
|
|
const fragment_program_type& fragmentProgramData,
|
|
|
|
|
const vk::pipeline_props& pipelineProperties,
|
|
|
|
|
bool compile_async,
|
|
|
|
|
std::function<pipeline_type*(pipeline_storage_type&)> callback,
|
2020-12-14 19:40:16 +01:00
|
|
|
VkPipelineLayout common_pipeline_layout)
|
2020-10-27 21:41:20 +01:00
|
|
|
{
|
|
|
|
|
const auto compiler_flags = compile_async ? vk::pipe_compiler::COMPILE_DEFERRED : vk::pipe_compiler::COMPILE_INLINE;
|
|
|
|
|
VkShaderModule modules[2] = { vertexProgramData.handle, fragmentProgramData.handle };
|
2019-09-17 14:44:03 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
auto compiler = vk::get_pipe_compiler();
|
|
|
|
|
auto result = compiler->compile(
|
|
|
|
|
pipelineProperties, modules, common_pipeline_layout,
|
|
|
|
|
compiler_flags, callback,
|
|
|
|
|
vertexProgramData.uniforms,
|
|
|
|
|
fragmentProgramData.uniforms);
|
2019-05-30 17:38:18 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
return callback(result);
|
2016-03-20 02:26:51 +01:00
|
|
|
}
|
|
|
|
|
};
|
2017-08-10 21:40:20 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
struct program_cache : public program_state_cache<VKTraits>
|
2016-02-21 16:50:49 +01:00
|
|
|
{
|
2020-10-27 21:41:20 +01:00
|
|
|
program_cache(decompiler_callback_t callback)
|
2019-10-28 22:07:38 +01:00
|
|
|
{
|
2020-10-27 21:41:20 +01:00
|
|
|
notify_pipeline_compiled = callback;
|
2019-10-28 22:07:38 +01:00
|
|
|
}
|
|
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
u64 get_hash(const vk::pipeline_props& props)
|
2019-05-30 17:38:18 +02:00
|
|
|
{
|
2020-10-27 21:41:20 +01:00
|
|
|
return rpcs3::hash_struct<vk::pipeline_props>(props);
|
2019-05-30 17:38:18 +02:00
|
|
|
}
|
2016-03-20 02:26:51 +01:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
u64 get_hash(const RSXVertexProgram& prog)
|
|
|
|
|
{
|
|
|
|
|
return program_hash_util::vertex_program_utils::get_vertex_program_ucode_hash(prog);
|
|
|
|
|
}
|
2017-08-09 13:30:15 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
u64 get_hash(const RSXFragmentProgram& prog)
|
|
|
|
|
{
|
|
|
|
|
return program_hash_util::fragment_program_utils::get_fragment_program_ucode_hash(prog);
|
|
|
|
|
}
|
2017-08-09 13:30:15 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
template <typename... Args>
|
|
|
|
|
void add_pipeline_entry(RSXVertexProgram& vp, RSXFragmentProgram& fp, vk::pipeline_props& props, Args&& ...args)
|
|
|
|
|
{
|
|
|
|
|
get_graphics_pipeline(vp, fp, props, false, false, std::forward<Args>(args)...);
|
|
|
|
|
}
|
2017-08-09 13:30:15 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
void preload_programs(RSXVertexProgram& vp, RSXFragmentProgram& fp)
|
|
|
|
|
{
|
|
|
|
|
search_vertex_program(vp);
|
|
|
|
|
search_fragment_program(fp);
|
|
|
|
|
}
|
2018-06-01 18:49:29 +02:00
|
|
|
|
2020-10-27 21:41:20 +01:00
|
|
|
bool check_cache_missed() const
|
|
|
|
|
{
|
|
|
|
|
return m_cache_miss_flag;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|