vk: Pass draw parameters to FS via varying register

- Should be better than pointer chasing with OpAccessChain + OpLoad
This commit is contained in:
kd-11 2025-08-18 01:21:58 +03:00 committed by kd-11
parent 2945ff1016
commit f76ae4619b
4 changed files with 19 additions and 33 deletions

View file

@ -20,7 +20,8 @@ namespace vk
{ "spec_color", 12 }, { "spec_color", 12 },
{ "spec_color1", 13 }, { "spec_color1", 13 },
{ "fog_c", 14 }, { "fog_c", 14 },
{ "fogc", 14 } { "fogc", 14 },
{ "usr", 15 }, // custom injected stuff
} }; } };
int get_varying_register_location(std::string_view varying_register_name) int get_varying_register_location(std::string_view varying_register_name)

View file

@ -166,24 +166,6 @@ void VKFragmentDecompilerThread::insertOutputs(std::stringstream & OS)
void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
{ {
// Declare push constants first to fix preprocessor references
OS <<
"layout(push_constant) uniform push_constants_block\n"
"{\n"
" uint draw_parameters_offset;\n"
"};\n\n";
const vk::glsl::program_input push_constants
{
.domain = glsl::glsl_fragment_program,
.type = vk::glsl::input_type_push_constant,
.bound_data = vk::glsl::push_constant_ref{.offset = 0, .size = 4 },
.set = vk::glsl::binding_set_index_vertex,
.location = umax,
.name = "fs_push_constants_block"
};
inputs.push_back(push_constants);
// Fixed inputs from shader decompilation process // Fixed inputs from shader decompilation process
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM]) for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
{ {
@ -244,19 +226,14 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
} }
} }
// Always provided by vertex program, not part of local bindings // Draw params are always provided by vertex program. Instead of pointer chasing, they're provided as varyings.
OS << OS <<
"layout(std430, set=0, binding=2) readonly buffer DrawParametersBuffer\n" "layout(location=" << vk::get_varying_register_location("usr") << ") in flat uvec4 draw_params_payload;\n\n"
"{\n"
" draw_parameters_t draw_parameters[];\n"
"};\n\n"
"draw_parameters_t get_draw_params() { return draw_parameters[draw_parameters_offset]; }\n\n" "#define _fs_constants_offset draw_params_payload.x\n"
"#define _fs_context_offset draw_params_payload.y\n"
"#define _fs_constants_offset get_draw_params().fs_constants_offset\n" "#define _fs_texture_base_index draw_params_payload.z\n"
"#define _fs_context_offset get_draw_params().fs_context_offset\n" "#define _fs_stipple_pattern_array_offset draw_params_payload.w\n\n";
"#define _fs_texture_base_index get_draw_params().fs_texture_base_index\n"
"#define _fs_stipple_pattern_array_offset get_draw_params().fs_stipple_pattern_offset\n\n";
if (!properties.constant_offsets.empty()) if (!properties.constant_offsets.empty())
{ {

View file

@ -2228,7 +2228,7 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_
vkCmdPushConstants( vkCmdPushConstants(
*m_current_command_buffer, *m_current_command_buffer,
m_program->layout(), m_program->layout(),
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_VERTEX_BIT,
0, 0,
4, 4,
&push_val); &push_val);

View file

@ -135,8 +135,7 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
.type = vk::glsl::input_type_storage_buffer, .type = vk::glsl::input_type_storage_buffer,
.set = vk::glsl::binding_set_index_vertex, .set = vk::glsl::binding_set_index_vertex,
.location = vk_prog->binding_table.vertex_buffers_location + 2, .location = vk_prog->binding_table.vertex_buffers_location + 2,
.name = "DrawParametersBuffer", .name = "DrawParametersBuffer"
.ex_stages = VK_SHADER_STAGE_FRAGMENT_BIT // Shared with fragment shader
}; };
inputs.push_back(layouts_input); inputs.push_back(layouts_input);
@ -312,6 +311,8 @@ void VKVertexDecompilerThread::insertOutputs(std::stringstream& OS, const std::v
OS << "layout(location=" << vk::get_varying_register_location(i.name) << ") out vec4 " << i.name << ";\n"; OS << "layout(location=" << vk::get_varying_register_location(i.name) << ") out vec4 " << i.name << ";\n";
} }
} }
OS << "layout(location=" << vk::get_varying_register_location("usr") << ") out flat uvec4 draw_params_payload;\n";
} }
void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS) void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS)
@ -412,6 +413,13 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
OS << " vs_main();\n\n"; OS << " vs_main();\n\n";
// FS payload
OS <<
"draw_params_payload.x = get_draw_params().fs_constants_offset;\n"
"draw_params_payload.y = get_draw_params().fs_context_offset;\n"
"draw_params_payload.z = get_draw_params().fs_texture_base_index;\n"
"draw_params_payload.w = get_draw_params().fs_stipple_pattern_offset;\n\n";
for (auto &i : reg_table) for (auto &i : reg_table)
{ {
if (!i.check_mask || i.test(rsx_vertex_program.output_mask)) if (!i.check_mask || i.test(rsx_vertex_program.output_mask))