mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
vk: Implement instancing when running in interpreter mode
This commit is contained in:
parent
ee1610eaf4
commit
bfb33aaeaa
3 changed files with 69 additions and 30 deletions
|
@ -1912,7 +1912,11 @@ bool VKGSRender::load_program()
|
|||
|
||||
if (shadermode == shader_mode::interpreter_only)
|
||||
{
|
||||
m_program = m_shader_interpreter.get(m_pipeline_properties, current_fp_metadata);
|
||||
m_program = m_shader_interpreter.get(
|
||||
m_pipeline_properties,
|
||||
current_fp_metadata,
|
||||
current_vertex_program.ctrl,
|
||||
current_fragment_program.ctrl);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2007,7 +2011,11 @@ bool VKGSRender::load_program()
|
|||
// First load the next program if not available
|
||||
if (!m_program)
|
||||
{
|
||||
m_program = m_shader_interpreter.get(m_pipeline_properties, current_fp_metadata);
|
||||
m_program = m_shader_interpreter.get(
|
||||
m_pipeline_properties,
|
||||
current_fp_metadata,
|
||||
current_vertex_program.ctrl,
|
||||
current_fragment_program.ctrl);
|
||||
|
||||
// Program has changed, reupload
|
||||
m_interpreter_state = rsx::invalidate_pipeline_bits;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace vk
|
||||
{
|
||||
void shader_interpreter::build_vs()
|
||||
glsl::shader* shader_interpreter::build_vs(u64 compiler_options)
|
||||
{
|
||||
::glsl::shader_properties properties{};
|
||||
properties.domain = ::glsl::program_domain::glsl_vertex_program;
|
||||
|
@ -24,6 +24,10 @@ namespace vk
|
|||
std::string shader_str;
|
||||
ParamArray arr;
|
||||
VKVertexProgram vk_prog;
|
||||
|
||||
null_prog.ctrl = (compiler_options & program_common::interpreter::COMPILER_OPT_ENABLE_INSTANCING)
|
||||
? RSX_SHADER_CONTROL_INSTANCED_CONSTANTS
|
||||
: 0;
|
||||
VKVertexDecompilerThread comp(null_prog, shader_str, arr, vk_prog);
|
||||
|
||||
ParamType uniforms = { PF_PARAM_UNIFORM, "vec4" };
|
||||
|
@ -45,14 +49,25 @@ namespace vk
|
|||
" uvec4 vp_instructions[];\n"
|
||||
"};\n\n";
|
||||
|
||||
if (compiler_options & program_common::interpreter::COMPILER_OPT_ENABLE_INSTANCING)
|
||||
{
|
||||
builder << "#define _ENABLE_INSTANCED_CONSTANTS\n";
|
||||
}
|
||||
|
||||
if (compiler_options)
|
||||
{
|
||||
builder << "\n";
|
||||
}
|
||||
|
||||
::glsl::insert_glsl_legacy_function(builder, properties);
|
||||
::glsl::insert_vertex_input_fetch(builder, ::glsl::glsl_rules::glsl_rules_vulkan);
|
||||
|
||||
builder << program_common::interpreter::get_vertex_interpreter();
|
||||
const std::string s = builder.str();
|
||||
|
||||
m_vs.create(::glsl::program_domain::glsl_vertex_program, s);
|
||||
m_vs.compile();
|
||||
auto vs = std::make_unique<glsl::shader>();
|
||||
vs->create(::glsl::program_domain::glsl_vertex_program, s);
|
||||
vs->compile();
|
||||
|
||||
// Prepare input table
|
||||
const auto& binding_table = vk::get_current_renderer()->get_pipeline_binding_table();
|
||||
|
@ -85,6 +100,10 @@ namespace vk
|
|||
m_vs_inputs.push_back(in);
|
||||
|
||||
// TODO: Bind textures if needed
|
||||
|
||||
auto ret = vs.get();
|
||||
m_shader_cache[compiler_options].m_vs = std::move(vs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
glsl::shader* shader_interpreter::build_fs(u64 compiler_options)
|
||||
|
@ -201,7 +220,7 @@ namespace vk
|
|||
builder << program_common::interpreter::get_fragment_interpreter();
|
||||
const std::string s = builder.str();
|
||||
|
||||
auto fs = new glsl::shader();
|
||||
auto fs = std::make_unique<glsl::shader>();
|
||||
fs->create(::glsl::program_domain::glsl_fragment_program, s);
|
||||
fs->compile();
|
||||
|
||||
|
@ -228,8 +247,9 @@ namespace vk
|
|||
m_fs_inputs.push_back(in);
|
||||
}
|
||||
|
||||
m_fs_cache[compiler_options].reset(fs);
|
||||
return fs;
|
||||
auto ret = fs.get();
|
||||
m_shader_cache[compiler_options].m_fs = std::move(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::pair<VkDescriptorSetLayout, VkPipelineLayout> shader_interpreter::create_layout(VkDevice dev)
|
||||
|
@ -359,10 +379,6 @@ namespace vk
|
|||
m_device = dev;
|
||||
std::tie(m_shared_descriptor_layout, m_shared_pipeline_layout) = create_layout(dev);
|
||||
create_descriptor_pools(dev);
|
||||
|
||||
rsx_log.notice("Building global vertex program interpreter...");
|
||||
build_vs();
|
||||
// TODO: Seed the cache
|
||||
}
|
||||
|
||||
void shader_interpreter::destroy()
|
||||
|
@ -370,13 +386,13 @@ namespace vk
|
|||
m_program_cache.clear();
|
||||
m_descriptor_pool.destroy();
|
||||
|
||||
for (auto &fs : m_fs_cache)
|
||||
for (auto &fs : m_shader_cache)
|
||||
{
|
||||
fs.second->destroy();
|
||||
fs.second.m_vs->destroy();
|
||||
fs.second.m_fs->destroy();
|
||||
}
|
||||
|
||||
m_vs.destroy();
|
||||
m_fs_cache.clear();
|
||||
m_shader_cache.clear();
|
||||
|
||||
if (m_shared_pipeline_layout)
|
||||
{
|
||||
|
@ -393,21 +409,22 @@ namespace vk
|
|||
|
||||
glsl::program* shader_interpreter::link(const vk::pipeline_props& properties, u64 compiler_opt)
|
||||
{
|
||||
glsl::shader* fs;
|
||||
if (auto found = m_fs_cache.find(compiler_opt); found != m_fs_cache.end())
|
||||
glsl::shader *fs, *vs;
|
||||
if (auto found = m_shader_cache.find(compiler_opt); found != m_shader_cache.end())
|
||||
{
|
||||
fs = found->second.get();
|
||||
fs = found->second.m_fs.get();
|
||||
vs = found->second.m_vs.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
rsx_log.notice("Compiling FS...");
|
||||
fs = build_fs(compiler_opt);
|
||||
vs = build_vs(compiler_opt);
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo shader_stages[2] = {};
|
||||
shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
shader_stages[0].module = m_vs.get_handle();
|
||||
shader_stages[0].module = vs->get_handle();
|
||||
shader_stages[0].pName = "main";
|
||||
|
||||
shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
|
@ -496,7 +513,11 @@ namespace vk
|
|||
return m_descriptor_pool.allocate(m_shared_descriptor_layout);
|
||||
}
|
||||
|
||||
glsl::program* shader_interpreter::get(const vk::pipeline_props& properties, const program_hash_util::fragment_program_utils::fragment_program_metadata& metadata)
|
||||
glsl::program* shader_interpreter::get(
|
||||
const vk::pipeline_props& properties,
|
||||
const program_hash_util::fragment_program_utils::fragment_program_metadata& metadata,
|
||||
u32 vp_ctrl,
|
||||
u32 fp_ctrl)
|
||||
{
|
||||
pipeline_key key;
|
||||
key.compiler_opt = 0;
|
||||
|
@ -531,13 +552,14 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
if (rsx::method_registers.shader_control() & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_DEPTH_EXPORT;
|
||||
if (rsx::method_registers.shader_control() & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_F32_EXPORT;
|
||||
if (rsx::method_registers.shader_control() & RSX_SHADER_CONTROL_USES_KIL) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_KIL;
|
||||
if (fp_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_DEPTH_EXPORT;
|
||||
if (fp_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_F32_EXPORT;
|
||||
if (fp_ctrl & RSX_SHADER_CONTROL_USES_KIL) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_KIL;
|
||||
if (metadata.referenced_textures_mask) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_TEXTURES;
|
||||
if (metadata.has_branch_instructions) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_FLOW_CTRL;
|
||||
if (metadata.has_pack_instructions) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_PACKING;
|
||||
if (rsx::method_registers.polygon_stipple_enabled()) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_STIPPLING;
|
||||
if (vp_ctrl & RSX_SHADER_CONTROL_INSTANCED_CONSTANTS) key.compiler_opt |= program_common::interpreter::COMPILER_OPT_ENABLE_INSTANCING;
|
||||
|
||||
if (m_current_key == key) [[likely]]
|
||||
{
|
||||
|
|
|
@ -12,8 +12,6 @@ namespace vk
|
|||
|
||||
class shader_interpreter
|
||||
{
|
||||
glsl::shader m_vs;
|
||||
|
||||
std::vector<glsl::program_input> m_vs_inputs;
|
||||
std::vector<glsl::program_input> m_fs_inputs;
|
||||
|
||||
|
@ -41,8 +39,14 @@ namespace vk
|
|||
}
|
||||
};
|
||||
|
||||
struct shader_cache_entry_t
|
||||
{
|
||||
std::unique_ptr<glsl::shader> m_fs;
|
||||
std::unique_ptr<glsl::shader> m_vs;
|
||||
};
|
||||
|
||||
std::unordered_map<pipeline_key, std::unique_ptr<glsl::program>, key_hasher> m_program_cache;
|
||||
std::unordered_map<u64, std::unique_ptr<glsl::shader>> m_fs_cache;
|
||||
std::unordered_map<u64, shader_cache_entry_t> m_shader_cache;
|
||||
rsx::simple_array<VkDescriptorPoolSize> m_descriptor_pool_sizes;
|
||||
vk::descriptor_pool m_descriptor_pool;
|
||||
|
||||
|
@ -55,7 +59,7 @@ namespace vk
|
|||
std::pair<VkDescriptorSetLayout, VkPipelineLayout> create_layout(VkDevice dev);
|
||||
void create_descriptor_pools(const vk::render_device& dev);
|
||||
|
||||
void build_vs();
|
||||
glsl::shader* build_vs(u64 compiler_opt);
|
||||
glsl::shader* build_fs(u64 compiler_opt);
|
||||
glsl::program* link(const vk::pipeline_props& properties, u64 compiler_opt);
|
||||
|
||||
|
@ -63,7 +67,12 @@ namespace vk
|
|||
void init(const vk::render_device& dev);
|
||||
void destroy();
|
||||
|
||||
glsl::program* get(const vk::pipeline_props& properties, const program_hash_util::fragment_program_utils::fragment_program_metadata& metadata);
|
||||
glsl::program* get(
|
||||
const vk::pipeline_props& properties,
|
||||
const program_hash_util::fragment_program_utils::fragment_program_metadata& metadata,
|
||||
u32 vp_ctrl,
|
||||
u32 fp_ctrl);
|
||||
|
||||
bool is_interpreter(const glsl::program* prog) const;
|
||||
|
||||
u32 get_vertex_instruction_location() const;
|
||||
|
|
Loading…
Add table
Reference in a new issue