vk: Move polygon stipple parameters to fixed array buffer

This commit is contained in:
kd-11 2025-08-06 01:53:09 +03:00 committed by kd-11
parent d68e4acb50
commit 6e4f380e36
7 changed files with 27 additions and 12 deletions

View file

@ -552,6 +552,9 @@ void main()
ur1 = ur0 & 31u; // address % 32 -> fetch bit offset
ur1 = (1u << ur1); // address mask
uvr0.x = (ur0 >> 7u); // address to uvec4 row (each row has 32x4 bits)
#ifdef VULKAN
uvr0.x += fs_stipple_pattern_array_offset; // Address base offset. Only applies to vulkan.
#endif
ur0 = (ur0 >> 5u) & 3u; // address to uvec4 word (address / 32) % 4
if ((stipple_pattern[uvr0.x][ur0] & ur1) == 0u)

View file

@ -32,6 +32,8 @@ struct draw_parameters_t
uint fs_constants_offset;
uint fs_context_offset;
uint fs_texture_base_index;
uint fs_stipple_pattern_offset;
uint reserved;
uvec2 attrib_data[16];
};

View file

@ -7,7 +7,12 @@ R"(
const uvec2 stipple_coord = uvec2(gl_FragCoord.xy) % uvec2(32, 32);
const uint address = stipple_coord.y * 32u + stipple_coord.x;
const uint bit_offset = (address & 31u);
#ifdef VULKAN
// In vulkan we have a unified array with a dynamic offset
const uint word_index = _get_bits(address, 7, 3) + fs_stipple_pattern_array_offset;
#else
const uint word_index = _get_bits(address, 7, 3);
#endif
const uint sub_index = _get_bits(address, 5, 2);
if (!_test_bit(stipple_pattern[word_index][sub_index], int(bit_offset)))

View file

@ -820,8 +820,8 @@ void VKGSRender::emit_geometry(u32 sub_index)
update_descriptors = true;
// Allocate stream layout memory for this batch
const u64 alloc_size = rsx::method_registers.current_draw_clause.pass_count() * 160;
m_vertex_layout_dynamic_offset = m_vertex_layout_ring_info.alloc<16>(alloc_size);
const u64 alloc_size = rsx::method_registers.current_draw_clause.pass_count() * 168;
m_vertex_layout_dynamic_offset = m_vertex_layout_ring_info.alloc<8>(alloc_size);
}
// Update vertex fetch parameters

View file

@ -235,7 +235,8 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
"#define get_draw_params() draw_parameters[draw_parameters_offset]\n"
"#define fs_constants_offset get_draw_params().fs_constants_offset\n"
"#define fs_context_offset get_draw_params().fs_context_offset\n"
"#define fs_texture_base_index get_draw_params().fs_texture_base_index\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())
{
@ -257,9 +258,9 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
OS << " sampler_info texture_parameters[];\n";
OS << "};\n\n";
OS << "layout(std140, set=1, binding=" << vk_prog->binding_table.polygon_stipple_params_location << ") uniform RasterizerHeap\n";
OS << "layout(std430, set=1, binding=" << vk_prog->binding_table.polygon_stipple_params_location << ") readonly buffer RasterizerHeap\n";
OS << "{\n";
OS << " uvec4 stipple_pattern[8];\n";
OS << " uvec4 stipple_pattern[];\n";
OS << "};\n\n";
vk::glsl::program_input in
@ -287,7 +288,7 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
inputs.push_back(in);
in.location = vk_prog->binding_table.polygon_stipple_params_location;
in.type = vk::glsl::input_type_uniform_buffer;
in.type = vk::glsl::input_type_storage_buffer;
in.name = "RasterizerHeap";
inputs.push_back(in);

View file

@ -555,7 +555,7 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar)
m_vertex_constants_buffer_info = { m_transform_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE };
m_fragment_env_buffer_info = { m_fragment_env_ring_info.heap->value, 0, VK_WHOLE_SIZE };
m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, 0, VK_WHOLE_SIZE };
m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, 0, 128 };
m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, 0, VK_WHOLE_SIZE };
m_vertex_layout_stream_info = { m_vertex_layout_ring_info.heap->value, 0, VK_WHOLE_SIZE };
m_fragment_constants_buffer_info = { m_fragment_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE };
@ -2038,12 +2038,11 @@ void VKGSRender::load_program_env()
if (update_raster_env)
{
auto mem = m_raster_env_ring_info.static_alloc<256>();
auto buf = m_raster_env_ring_info.map(mem, 128);
m_stipple_array_dynamic_offset = m_raster_env_ring_info.static_alloc<128>();
auto buf = m_raster_env_ring_info.map(m_stipple_array_dynamic_offset, 128);
std::memcpy(buf, ctx->polygon_stipple_pattern(), 128);
m_raster_env_ring_info.unmap();
m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, mem, 128 };
m_graphics_state.clear(rsx::pipeline_state::polygon_stipple_pattern_dirty);
}
@ -2194,6 +2193,8 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_
u32 fs_constants_offset;
u32 fs_context_offset;
u32 fs_texture_base_index;
u32 fs_stipple_pattern_offset;
u32 reserved;
s32 attrib_data[1];
};
#pragma pack(pop)
@ -2201,12 +2202,13 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_
// Actual allocation must have been done previously
const u32 vs_constant_id_offset = static_cast<u32>(m_xform_constants_dynamic_offset) / 16u;
const u32 vertex_context_offset = static_cast<u32>(m_vertex_env_dynamic_offset) / 96u;
const u32 vertex_layout_offset = static_cast<u32>(m_vertex_layout_dynamic_offset) / 160u;
const u32 vertex_layout_offset = static_cast<u32>(m_vertex_layout_dynamic_offset) / 168u;
const u32 fs_constant_id_offset = static_cast<u32>(m_fragment_constants_dynamic_offset) / 16u;
const u32 fs_context_offset = static_cast<u32>(m_fragment_env_dynamic_offset) / 32u;
const u32 fs_texture_base_index = static_cast<u32>(m_texture_parameters_dynamic_offset) / 48u;
const u32 fs_stipple_pattern_offset = static_cast<u32>(m_stipple_array_dynamic_offset) / 16u;
auto buf = m_vertex_layout_ring_info.map(m_vertex_layout_dynamic_offset + (160u * id), 160u);
auto buf = m_vertex_layout_ring_info.map(m_vertex_layout_dynamic_offset + (168u * id), 168u);
auto dst = reinterpret_cast<rsx_prog_vertex_layout_entry_t*>(buf);
// Pack
@ -2220,6 +2222,7 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_
dst->fs_constants_offset = fs_constant_id_offset;
dst->fs_context_offset = fs_context_offset;
dst->fs_texture_base_index = fs_texture_base_index;
dst->fs_stipple_pattern_offset = fs_stipple_pattern_offset;
const u32 push_val = vertex_layout_offset + id;
vkCmdPushConstants(

View file

@ -156,6 +156,7 @@ private:
u64 m_fragment_constants_dynamic_offset = 0;
u64 m_fragment_env_dynamic_offset = 0;
u64 m_texture_parameters_dynamic_offset = 0;
u64 m_stipple_array_dynamic_offset = 0;
std::array<vk::frame_context_t, VK_MAX_ASYNC_FRAMES> frame_context_storage;
//Temp frame context to use if the real frame queue is overburdened. Only used for storage