vk: Make buffer objects uniquely identifiable

This commit is contained in:
kd-11 2025-10-17 03:36:14 +03:00 committed by kd-11
parent eb453462c1
commit 0d1a05ecd1
11 changed files with 71 additions and 56 deletions

View file

@ -246,7 +246,7 @@ namespace vk
void cs_shuffle_base::bind_resources(const vk::command_buffer& cmd) void cs_shuffle_base::bind_resources(const vk::command_buffer& cmd)
{ {
set_parameters(cmd); set_parameters(cmd);
m_program->bind_uniform({ m_data->value, m_data_offset, m_data_length }, 0, 0); m_program->bind_uniform({ *m_data, m_data_offset, m_data_length }, 0, 0);
} }
void cs_shuffle_base::set_parameters(const vk::command_buffer& cmd) void cs_shuffle_base::set_parameters(const vk::command_buffer& cmd)
@ -296,7 +296,7 @@ namespace vk
void cs_interleave_task::bind_resources(const vk::command_buffer& cmd) void cs_interleave_task::bind_resources(const vk::command_buffer& cmd)
{ {
set_parameters(cmd); set_parameters(cmd);
m_program->bind_uniform({ m_data->value, m_data_offset, m_ssbo_length }, 0, 0); m_program->bind_uniform({ *m_data, m_data_offset, m_ssbo_length }, 0, 0);
} }
void cs_interleave_task::run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_offset, u32 data_length, u32 zeta_offset, u32 stencil_offset) void cs_interleave_task::run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_offset, u32 data_length, u32 zeta_offset, u32 stencil_offset)
@ -355,8 +355,8 @@ namespace vk
void cs_aggregator::bind_resources(const vk::command_buffer& /*cmd*/) void cs_aggregator::bind_resources(const vk::command_buffer& /*cmd*/)
{ {
m_program->bind_uniform({ src->value, 0, block_length }, 0, 0); m_program->bind_uniform({ *src, 0, block_length }, 0, 0);
m_program->bind_uniform({ dst->value, 0, 4 }, 0, 1); m_program->bind_uniform({ *dst, 0, 4 }, 0, 1);
} }
void cs_aggregator::run(const vk::command_buffer& cmd, const vk::buffer* dst, const vk::buffer* src, u32 num_words) void cs_aggregator::run(const vk::command_buffer& cmd, const vk::buffer* dst, const vk::buffer* src, u32 num_words)

View file

@ -347,7 +347,7 @@ namespace vk
void bind_resources(const vk::command_buffer& cmd) override void bind_resources(const vk::command_buffer& cmd) override
{ {
set_parameters(cmd); set_parameters(cmd);
m_program->bind_uniform({ m_data->value, m_data_offset, m_ssbo_length }, 0, 0); m_program->bind_uniform({ *m_data, m_data_offset, m_ssbo_length }, 0, 0);
} }
void run(const vk::command_buffer& cmd, const vk::buffer* data, u32 src_offset, u32 src_length, u32 dst_offset) void run(const vk::command_buffer& cmd, const vk::buffer* data, u32 src_offset, u32 src_length, u32 dst_offset)
@ -449,8 +449,8 @@ namespace vk
{ {
set_parameters(cmd); set_parameters(cmd);
m_program->bind_uniform({ src_buffer->value, in_offset, block_length }, 0, 0); m_program->bind_uniform({ *src_buffer, in_offset, block_length }, 0, 0);
m_program->bind_uniform({ dst_buffer->value, out_offset, block_length }, 0, 1); m_program->bind_uniform({ *dst_buffer, out_offset, block_length }, 0, 1);
} }
void set_parameters(const vk::command_buffer& cmd) void set_parameters(const vk::command_buffer& cmd)
@ -579,8 +579,8 @@ namespace vk
set_parameters(cmd); set_parameters(cmd);
const auto op = static_cast<u32>(Op); const auto op = static_cast<u32>(Op);
m_program->bind_uniform({ src_buffer->value, in_offset, in_block_length }, 0u, 0u ^ op); m_program->bind_uniform({ *src_buffer, in_offset, in_block_length }, 0u, 0u ^ op);
m_program->bind_uniform({ dst_buffer->value, out_offset, out_block_length }, 0u, 1u ^ op); m_program->bind_uniform({ *dst_buffer, out_offset, out_block_length }, 0u, 1u ^ op);
} }
void set_parameters(const vk::command_buffer& cmd) void set_parameters(const vk::command_buffer& cmd)

View file

@ -553,13 +553,13 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar)
} }
// Initialize optional allocation information with placeholders // Initialize optional allocation information with placeholders
m_vertex_env_buffer_info = { m_vertex_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_vertex_env_buffer_info = { *m_vertex_env_ring_info.heap, 0, VK_WHOLE_SIZE };
m_vertex_constants_buffer_info = { m_transform_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_vertex_constants_buffer_info = { *m_transform_constants_ring_info.heap, 0, VK_WHOLE_SIZE };
m_fragment_env_buffer_info = { m_fragment_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_env_buffer_info = { *m_fragment_env_ring_info.heap, 0, VK_WHOLE_SIZE };
m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_texture_params_buffer_info = { *m_fragment_texture_params_ring_info.heap, 0, VK_WHOLE_SIZE };
m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_raster_env_buffer_info = { *m_raster_env_ring_info.heap, 0, VK_WHOLE_SIZE };
m_vertex_layout_stream_info = { m_vertex_layout_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_vertex_layout_stream_info = { *m_vertex_layout_ring_info.heap, 0, VK_WHOLE_SIZE };
m_fragment_constants_buffer_info = { m_fragment_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_constants_buffer_info = { *m_fragment_constants_ring_info.heap, 0, VK_WHOLE_SIZE };
const auto& limits = m_device->gpu().get_limits(); const auto& limits = m_device->gpu().get_limits();
m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000u); m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000u);
@ -1980,8 +1980,8 @@ void VKGSRender::load_program_env()
m_draw_processor.fill_constants_instancing_buffer(indirection_table_buf, constants_array_buf, bound_vertex_prog); m_draw_processor.fill_constants_instancing_buffer(indirection_table_buf, constants_array_buf, bound_vertex_prog);
m_instancing_buffer_ring_info.unmap(); m_instancing_buffer_ring_info.unmap();
m_instancing_indirection_buffer_info = { m_instancing_buffer_ring_info.heap->value, indirection_table_offset, indirection_table_buf.size() }; m_instancing_indirection_buffer_info = { *m_instancing_buffer_ring_info.heap, indirection_table_offset, indirection_table_buf.size() };
m_instancing_constants_array_buffer_info = { m_instancing_buffer_ring_info.heap->value, constants_data_table_offset, constants_array_buf.size() }; m_instancing_constants_array_buffer_info = { *m_instancing_buffer_ring_info.heap, constants_data_table_offset, constants_array_buf.size() };
} }
else if (update_transform_constants) else if (update_transform_constants)
{ {
@ -2066,7 +2066,7 @@ void VKGSRender::load_program_env()
std::memcpy(vp_buf + 16, current_vertex_program.data.data(), current_vp_metadata.ucode_length); std::memcpy(vp_buf + 16, current_vertex_program.data.data(), current_vp_metadata.ucode_length);
m_vertex_instructions_buffer.unmap(); m_vertex_instructions_buffer.unmap();
m_vertex_instructions_buffer_info = { m_vertex_instructions_buffer.heap->value, vp_mapping, vp_block_length }; m_vertex_instructions_buffer_info = { *m_vertex_instructions_buffer.heap, vp_mapping, vp_block_length };
} }
if (m_interpreter_state & rsx::fragment_program_dirty) if (m_interpreter_state & rsx::fragment_program_dirty)
@ -2084,7 +2084,7 @@ void VKGSRender::load_program_env()
std::memcpy(fp_buf + 16, current_fragment_program.get_data(), current_fragment_program.ucode_length); std::memcpy(fp_buf + 16, current_fragment_program.get_data(), current_fragment_program.ucode_length);
m_fragment_instructions_buffer.unmap(); m_fragment_instructions_buffer.unmap();
m_fragment_instructions_buffer_info = { m_fragment_instructions_buffer.heap->value, fp_mapping, fp_block_length }; m_fragment_instructions_buffer_info = { *m_fragment_instructions_buffer.heap, fp_mapping, fp_block_length };
} }
} }
@ -2111,7 +2111,7 @@ void VKGSRender::load_program_env()
if (vk::emulate_conditional_rendering()) if (vk::emulate_conditional_rendering())
{ {
const VkBuffer predicate = m_cond_render_buffer ? m_cond_render_buffer->value : vk::get_scratch_buffer(*m_current_command_buffer, 4)->value; const vk::buffer& predicate = m_cond_render_buffer ? *m_cond_render_buffer : *vk::get_scratch_buffer(*m_current_command_buffer, 4);
const u32 offset = cond_render_ctrl.hw_cond_active ? 0 : 4; const u32 offset = cond_render_ctrl.hw_cond_active ? 0 : 4;
m_program->bind_uniform({ predicate, offset, 4 }, vk::glsl::binding_set_index_vertex, m_vs_binding_table->cr_pred_buffer_location); m_program->bind_uniform({ predicate, offset, 4 }, vk::glsl::binding_set_index_vertex, m_vs_binding_table->cr_pred_buffer_location);
} }

View file

@ -4,6 +4,7 @@
#include "vkutils/descriptors.h" #include "vkutils/descriptors.h"
#include "vkutils/data_heap.h" #include "vkutils/data_heap.h"
#include "vkutils/ex.h"
#include "vkutils/instance.h" #include "vkutils/instance.h"
#include "vkutils/sync.h" #include "vkutils/sync.h"
#include "vkutils/swapchain.h" #include "vkutils/swapchain.h"
@ -136,18 +137,18 @@ private:
vk::data_heap m_fragment_instructions_buffer; vk::data_heap m_fragment_instructions_buffer;
vk::data_heap m_vertex_instructions_buffer; vk::data_heap m_vertex_instructions_buffer;
VkDescriptorBufferInfo m_vertex_env_buffer_info {}; VkDescriptorBufferInfoEx m_vertex_env_buffer_info {};
VkDescriptorBufferInfo m_fragment_env_buffer_info {}; VkDescriptorBufferInfoEx m_fragment_env_buffer_info {};
VkDescriptorBufferInfo m_vertex_layout_stream_info {}; VkDescriptorBufferInfoEx m_vertex_layout_stream_info {};
VkDescriptorBufferInfo m_vertex_constants_buffer_info {}; VkDescriptorBufferInfoEx m_vertex_constants_buffer_info {};
VkDescriptorBufferInfo m_fragment_constants_buffer_info {}; VkDescriptorBufferInfoEx m_fragment_constants_buffer_info {};
VkDescriptorBufferInfo m_fragment_texture_params_buffer_info {}; VkDescriptorBufferInfoEx m_fragment_texture_params_buffer_info {};
VkDescriptorBufferInfo m_raster_env_buffer_info {}; VkDescriptorBufferInfoEx m_raster_env_buffer_info {};
VkDescriptorBufferInfo m_instancing_indirection_buffer_info {}; VkDescriptorBufferInfoEx m_instancing_indirection_buffer_info {};
VkDescriptorBufferInfo m_instancing_constants_array_buffer_info{}; VkDescriptorBufferInfoEx m_instancing_constants_array_buffer_info{};
VkDescriptorBufferInfo m_vertex_instructions_buffer_info {}; VkDescriptorBufferInfoEx m_vertex_instructions_buffer_info {};
VkDescriptorBufferInfo m_fragment_instructions_buffer_info {}; VkDescriptorBufferInfoEx m_fragment_instructions_buffer_info {};
rsx::simple_array<u8> m_multidraw_parameters_buffer; rsx::simple_array<u8> m_multidraw_parameters_buffer;
u64 m_xform_constants_dynamic_offset = 0; // We manage transform_constants dynamic offset manually to alleviate performance penalty of doing a hot-patch of constants. u64 m_xform_constants_dynamic_offset = 0; // We manage transform_constants dynamic offset manually to alleviate performance penalty of doing a hot-patch of constants.

View file

@ -183,7 +183,7 @@ namespace vk
if (m_num_uniform_buffers > 0) if (m_num_uniform_buffers > 0)
{ {
program->bind_uniform({ m_ubo.heap->value, m_ubo_offset, std::max(m_ubo_length, 4u) }, 0, 0); program->bind_uniform({ *m_ubo.heap, m_ubo_offset, std::max(m_ubo_length, 4u) }, 0, 0);
} }
for (uint n = 0; n < src.size(); ++n) for (uint n = 0; n < src.size(); ++n)

View file

@ -20,13 +20,10 @@ namespace vk
return !!ptr && ptr->resourceId == b.resourceId; return !!ptr && ptr->resourceId == b.resourceId;
} }
bool operator == (const descriptor_slot_t& a, const VkDescriptorBufferInfo& b) bool operator == (const descriptor_slot_t& a, const VkDescriptorBufferInfoEx& b)
{ {
const auto ptr = std::get_if<VkDescriptorBufferInfo>(&a); const auto ptr = std::get_if<VkDescriptorBufferInfoEx>(&a);
return !!ptr && return !!ptr && ptr->resourceId == b.resourceId;
ptr->buffer == b.buffer &&
ptr->offset == b.offset &&
ptr->range == b.range;
} }
bool operator == (const descriptor_slot_t& a, const VkDescriptorBufferViewEx& b) bool operator == (const descriptor_slot_t& a, const VkDescriptorBufferViewEx& b)
@ -320,7 +317,7 @@ namespace vk
m_sets[set_id].notify_descriptor_slot_updated(binding_point, image_descriptor); m_sets[set_id].notify_descriptor_slot_updated(binding_point, image_descriptor);
} }
void program::bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, u32 set_id, u32 binding_point) void program::bind_uniform(const VkDescriptorBufferInfoEx &buffer_descriptor, u32 set_id, u32 binding_point)
{ {
if (m_sets[set_id].m_descriptor_slots[binding_point] == buffer_descriptor) if (m_sets[set_id].m_descriptor_slots[binding_point] == buffer_descriptor)
{ {
@ -482,7 +479,7 @@ namespace vk
return; return;
} }
if (auto ptr = std::get_if<VkDescriptorBufferInfo>(&slot)) if (auto ptr = std::get_if<VkDescriptorBufferInfoEx>(&slot))
{ {
m_descriptor_set.push(*ptr, type, idx); m_descriptor_set.push(*ptr, type, idx);
return; return;
@ -533,7 +530,7 @@ namespace vk
return; return;
} }
if (auto ptr = std::get_if<VkDescriptorBufferInfo>(&slot)) if (auto ptr = std::get_if<VkDescriptorBufferInfoEx>(&slot))
{ {
m_descriptor_template[idx].pBufferInfo = m_descriptor_set.store(*ptr); m_descriptor_template[idx].pBufferInfo = m_descriptor_set.store(*ptr);
return; return;

View file

@ -115,7 +115,11 @@ namespace vk
}; };
using descriptor_image_array_t = rsx::simple_array<VkDescriptorImageInfoEx>; using descriptor_image_array_t = rsx::simple_array<VkDescriptorImageInfoEx>;
using descriptor_slot_t = std::variant<VkDescriptorImageInfoEx, VkDescriptorBufferInfo, VkDescriptorBufferViewEx, descriptor_image_array_t>; using descriptor_slot_t = std::variant<
VkDescriptorImageInfoEx,
VkDescriptorBufferInfoEx,
VkDescriptorBufferViewEx,
descriptor_image_array_t>;
struct descriptor_table_t struct descriptor_table_t
{ {
@ -202,7 +206,7 @@ namespace vk
std::pair<u32, u32> get_uniform_location(::glsl::program_domain domain, program_input_type type, const std::string& uniform_name); std::pair<u32, u32> get_uniform_location(::glsl::program_domain domain, program_input_type type, const std::string& uniform_name);
void bind_uniform(const VkDescriptorImageInfoEx& image_descriptor, u32 set_id, u32 binding_point); void bind_uniform(const VkDescriptorImageInfoEx& image_descriptor, u32 set_id, u32 binding_point);
void bind_uniform(const VkDescriptorBufferInfo& buffer_descriptor, u32 set_id, u32 binding_point); void bind_uniform(const VkDescriptorBufferInfoEx& buffer_descriptor, u32 set_id, u32 binding_point);
void bind_uniform(const VkDescriptorBufferViewEx& buffer_view, u32 set_id, u32 binding_point); void bind_uniform(const VkDescriptorBufferViewEx& buffer_view, u32 set_id, u32 binding_point);
void bind_uniform(const VkDescriptorBufferViewEx& buffer_view, ::glsl::program_domain domain, program_input_type type, const std::string &binding_name); void bind_uniform(const VkDescriptorBufferViewEx& buffer_view, ::glsl::program_domain domain, program_input_type type, const std::string &binding_name);

View file

@ -329,13 +329,13 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data()
vk::get_resource_manager()->dispose(m_volatile_attribute_storage); vk::get_resource_manager()->dispose(m_volatile_attribute_storage);
} }
m_vertex_env_buffer_info = { m_vertex_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_vertex_env_buffer_info = { *m_vertex_env_ring_info.heap, 0, VK_WHOLE_SIZE };
m_vertex_constants_buffer_info = { m_transform_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_vertex_constants_buffer_info = { *m_transform_constants_ring_info.heap, 0, VK_WHOLE_SIZE };
m_fragment_env_buffer_info = { m_fragment_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_env_buffer_info = { *m_fragment_env_ring_info.heap, 0, VK_WHOLE_SIZE };
m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_texture_params_buffer_info = { *m_fragment_texture_params_ring_info.heap, 0, VK_WHOLE_SIZE };
m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_raster_env_buffer_info = { *m_raster_env_ring_info.heap, 0, VK_WHOLE_SIZE };
m_vertex_layout_stream_info = { m_vertex_layout_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_vertex_layout_stream_info = { *m_vertex_layout_ring_info.heap, 0, VK_WHOLE_SIZE };
m_fragment_constants_buffer_info = { m_fragment_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_constants_buffer_info = { *m_fragment_constants_ring_info.heap, 0, VK_WHOLE_SIZE };
vk::clear_status_interrupt(vk::heap_changed); vk::clear_status_interrupt(vk::heap_changed);
} }

View file

@ -24,7 +24,7 @@ namespace vk
VkDevice m_device; VkDevice m_device;
}; };
struct buffer struct buffer : public unique_resource
{ {
VkBuffer value; VkBuffer value;
VkBufferCreateInfo info = {}; VkBufferCreateInfo info = {};

View file

@ -29,4 +29,9 @@ namespace vk
: resourceId(view.uid()) : resourceId(view.uid())
, view(view.value) , view(view.value)
{} {}
VkDescriptorBufferInfoEx::VkDescriptorBufferInfoEx(const vk::buffer& buffer, u64 offset, u64 range)
: VkDescriptorBufferInfo(buffer.value, offset, range)
, resourceId(buffer.uid())
{}
} }

View file

@ -5,6 +5,7 @@
// Custom extensions to vulkan core // Custom extensions to vulkan core
namespace vk namespace vk
{ {
struct buffer;
struct buffer_view; struct buffer_view;
struct image_view; struct image_view;
struct sampler; struct sampler;
@ -22,19 +23,26 @@ namespace vk
VkDescriptorImageInfoEx(const vk::image_view& view); VkDescriptorImageInfoEx(const vk::image_view& view);
}; };
struct VkDescriptorBufferViewEx { struct VkDescriptorBufferViewEx
{
u64 resourceId = 0ull; u64 resourceId = 0ull;
VkBufferView view = VK_NULL_HANDLE; VkBufferView view = VK_NULL_HANDLE;
VkDescriptorBufferViewEx() = default; VkDescriptorBufferViewEx() = default;
VkDescriptorBufferViewEx(u64 uid, VkBufferView view)
: resourceId(uid), view(view)
{}
VkDescriptorBufferViewEx(const vk::buffer_view& view); VkDescriptorBufferViewEx(const vk::buffer_view& view);
}; };
struct VkDescriptorBufferInfoEx : public VkDescriptorBufferInfo
{
u64 resourceId = 0ull;
VkDescriptorBufferInfoEx() = default;
VkDescriptorBufferInfoEx(const vk::buffer& buffer, u64 offset, u64 range);
};
} }
// Re-export // Re-export
using VkDescriptorImageInfoEx = vk::VkDescriptorImageInfoEx; using VkDescriptorImageInfoEx = vk::VkDescriptorImageInfoEx;
using VkDescriptorBufferViewEx = vk::VkDescriptorBufferViewEx; using VkDescriptorBufferViewEx = vk::VkDescriptorBufferViewEx;
using VkDescriptorBufferInfoEx = vk::VkDescriptorBufferInfoEx;