mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-01-10 02:30:07 +01:00
vk: Fix shader interpreter compilation and crashes
This commit is contained in:
parent
efa4c6c34e
commit
afb814788f
|
|
@ -71,7 +71,7 @@ namespace vk
|
|||
|
||||
// Initialize binding layout
|
||||
auto vk_prog = std::make_unique<VKVertexProgram>();
|
||||
m_vertex_instruction_start = init(vk_prog.get(), compiler_options);
|
||||
const u32 vertex_instruction_start = init(vk_prog.get(), compiler_options);
|
||||
|
||||
null_prog.ctrl = (compiler_options & program_common::interpreter::COMPILER_OPT_ENABLE_INSTANCING)
|
||||
? RSX_SHADER_CONTROL_INSTANCED_CONSTANTS
|
||||
|
|
@ -93,6 +93,7 @@ namespace vk
|
|||
builder << "layout(location=16) out flat uvec4 draw_params_payload;\n\n";
|
||||
|
||||
builder <<
|
||||
"#define xform_constants_offset get_draw_params().xform_constants_offset\n"
|
||||
"#define scale_offset_mat get_vertex_context().scale_offset_mat\n"
|
||||
"#define transform_branch_bits get_vertex_context().transform_branch_bits\n"
|
||||
"#define point_size get_vertex_context().point_size\n"
|
||||
|
|
@ -101,7 +102,7 @@ namespace vk
|
|||
|
||||
// Insert vp stream input
|
||||
builder << "\n"
|
||||
"layout(std140, set=0, binding=" << m_vertex_instruction_start << ") readonly restrict buffer VertexInstructionBlock\n"
|
||||
"layout(std140, set=0, binding=" << vertex_instruction_start << ") readonly restrict buffer VertexInstructionBlock\n"
|
||||
"{\n"
|
||||
" uint base_address;\n"
|
||||
" uint entry;\n"
|
||||
|
|
@ -143,7 +144,7 @@ namespace vk
|
|||
vk::glsl::program_input in;
|
||||
in.set = 0;
|
||||
in.domain = ::glsl::glsl_vertex_program;
|
||||
in.location = m_vertex_instruction_start;
|
||||
in.location = vertex_instruction_start;
|
||||
in.type = glsl::input_type_storage_buffer;
|
||||
in.name = "VertexInstructionBlock";
|
||||
vs_inputs.push_back(in);
|
||||
|
|
@ -170,8 +171,8 @@ namespace vk
|
|||
frag.ctrl |= RSX_SHADER_CONTROL_INTERPRETER_MODEL;
|
||||
|
||||
auto vk_prog = std::make_unique<VKFragmentProgram>();
|
||||
m_fragment_instruction_start = init(vk_prog.get(), compiler_options);
|
||||
m_fragment_textures_start = m_fragment_instruction_start + 1;
|
||||
const u32 fragment_instruction_start = init(vk_prog.get(), compiler_options);
|
||||
const u32 fragment_textures_start = fragment_instruction_start + 1;
|
||||
|
||||
VKFragmentDecompilerThread comp(shader_str, arr, frag, len, *vk_prog);
|
||||
|
||||
|
|
@ -257,7 +258,7 @@ namespace vk
|
|||
{
|
||||
builder << "#define WITH_TEXTURES\n\n";
|
||||
|
||||
for (int i = 0, bind_location = m_fragment_textures_start; i < 4; ++i)
|
||||
for (int i = 0, bind_location = fragment_textures_start; i < 4; ++i)
|
||||
{
|
||||
builder << "layout(set=1, binding=" << bind_location++ << ") " << "uniform " << type_names[i] << " " << type_names[i] << "_array[16];\n";
|
||||
}
|
||||
|
|
@ -272,7 +273,7 @@ namespace vk
|
|||
}
|
||||
|
||||
builder <<
|
||||
"layout(std430, set=1, binding=" << m_fragment_instruction_start << ") readonly restrict buffer FragmentInstructionBlock\n"
|
||||
"layout(std430, set=1, binding=" << fragment_instruction_start << ") readonly restrict buffer FragmentInstructionBlock\n"
|
||||
"{\n"
|
||||
" uint shader_control;\n"
|
||||
" uint texture_control;\n"
|
||||
|
|
@ -298,14 +299,14 @@ namespace vk
|
|||
vk::glsl::program_input in;
|
||||
in.set = 1;
|
||||
in.domain = ::glsl::glsl_fragment_program;
|
||||
in.location = m_fragment_instruction_start;
|
||||
in.location = fragment_instruction_start;
|
||||
in.type = glsl::input_type_storage_buffer;
|
||||
in.name = "FragmentInstructionBlock";
|
||||
inputs.push_back(in);
|
||||
|
||||
if (compiler_options & program_common::interpreter::COMPILER_OPT_ENABLE_TEXTURES)
|
||||
{
|
||||
for (int i = 0, location = m_fragment_textures_start; i < 4; ++i, ++location)
|
||||
for (int i = 0, location = fragment_textures_start; i < 4; ++i, ++location)
|
||||
{
|
||||
in.location = location;
|
||||
in.name = std::string(type_names[i]) + "_array[16]";
|
||||
|
|
@ -504,6 +505,7 @@ namespace vk
|
|||
}
|
||||
else
|
||||
{
|
||||
m_current_pipeline_info_ex = *get_pipeline_info_ex(key.compiler_opt);
|
||||
m_current_key = key;
|
||||
}
|
||||
|
||||
|
|
@ -526,12 +528,12 @@ namespace vk
|
|||
|
||||
u32 shader_interpreter::get_vertex_instruction_location() const
|
||||
{
|
||||
return m_vertex_instruction_start;
|
||||
return m_current_pipeline_info_ex.vertex_instruction_location;
|
||||
}
|
||||
|
||||
u32 shader_interpreter::get_fragment_instruction_location() const
|
||||
{
|
||||
return m_fragment_instruction_start;
|
||||
return m_current_pipeline_info_ex.fragment_instruction_location;
|
||||
}
|
||||
|
||||
std::pair<VKVertexProgram*, VKFragmentProgram*> shader_interpreter::get_shaders() const
|
||||
|
|
@ -545,4 +547,27 @@ namespace vk
|
|||
|
||||
return { nullptr, nullptr };
|
||||
}
|
||||
|
||||
const shader_interpreter::pipeline_info_ex_t* shader_interpreter::get_pipeline_info_ex(u64 compiler_opt)
|
||||
{
|
||||
if (auto found = m_pipeline_info_cache.find(compiler_opt); found != m_pipeline_info_cache.end())
|
||||
{
|
||||
return &found->second;
|
||||
}
|
||||
|
||||
VKVertexProgram vs_stub{};
|
||||
VKFragmentProgram fs_stub{};
|
||||
const auto vi_location = init(&vs_stub, compiler_opt);
|
||||
const auto fi_location = init(&fs_stub, compiler_opt);
|
||||
|
||||
pipeline_info_ex_t result
|
||||
{
|
||||
.vertex_instruction_location = vi_location,
|
||||
.fragment_instruction_location = fi_location,
|
||||
.fragment_textures_location = fi_location + 1
|
||||
};
|
||||
|
||||
auto it = m_pipeline_info_cache.insert_or_assign(compiler_opt, result);
|
||||
return &it.first->second;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,14 +43,19 @@ namespace vk
|
|||
std::unique_ptr<VKVertexProgram> m_vs;
|
||||
};
|
||||
|
||||
struct pipeline_info_ex_t
|
||||
{
|
||||
u32 vertex_instruction_location = 0;
|
||||
u32 fragment_instruction_location = 0;
|
||||
u32 fragment_textures_location = 0;
|
||||
};
|
||||
|
||||
std::unordered_map<pipeline_key, std::unique_ptr<glsl::program>, key_hasher> m_program_cache;
|
||||
std::unordered_map<u64, shader_cache_entry_t> m_shader_cache;
|
||||
|
||||
u32 m_vertex_instruction_start = 0;
|
||||
u32 m_fragment_instruction_start = 0;
|
||||
u32 m_fragment_textures_start = 0;
|
||||
std::unordered_map<u64, pipeline_info_ex_t> m_pipeline_info_cache;
|
||||
|
||||
pipeline_key m_current_key{};
|
||||
pipeline_info_ex_t m_current_pipeline_info_ex{};
|
||||
|
||||
VKVertexProgram* build_vs(u64 compiler_opt);
|
||||
VKFragmentProgram* build_fs(u64 compiler_opt);
|
||||
|
|
@ -59,6 +64,8 @@ namespace vk
|
|||
u32 init(VKVertexProgram* vk_prog, u64 compiler_opt) const;
|
||||
u32 init(VKFragmentProgram* vk_prog, u64 compiler_opt) const;
|
||||
|
||||
const pipeline_info_ex_t* get_pipeline_info_ex(u64 compiler_opt);
|
||||
|
||||
public:
|
||||
void init(const vk::render_device& dev);
|
||||
void destroy();
|
||||
|
|
|
|||
Loading…
Reference in a new issue