vk: Fix shader interpreter compilation and crashes

This commit is contained in:
kd-11 2025-08-29 03:48:19 +03:00 committed by kd-11
parent efa4c6c34e
commit afb814788f
2 changed files with 47 additions and 15 deletions

View file

@ -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;
}
};

View file

@ -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();