mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 06:51:26 +12:00
vk: Spec compliance.
- TODO: Implement push_constants path instead of copy + bind descriptor sets
This commit is contained in:
parent
d6b4440ef9
commit
26a56ef1f1
3 changed files with 82 additions and 42 deletions
|
@ -655,7 +655,7 @@ VKGSRender::VKGSRender() : GSRender()
|
||||||
m_texture_upload_buffer_ring_info.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, "texture upload buffer", 32 * 0x100000);
|
m_texture_upload_buffer_ring_info.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, "texture upload buffer", 32 * 0x100000);
|
||||||
|
|
||||||
const auto limits = m_device->gpu().get_limits();
|
const auto limits = m_device->gpu().get_limits();
|
||||||
m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, 0x4000000u);
|
m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000u);
|
||||||
|
|
||||||
if (m_texbuffer_view_size < 0x800000)
|
if (m_texbuffer_view_size < 0x800000)
|
||||||
{
|
{
|
||||||
|
@ -1029,6 +1029,38 @@ void VKGSRender::check_heap_status()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VKGSRender::check_descriptors()
|
||||||
|
{
|
||||||
|
// Ease resource pressure if the number of draw calls becomes too high or we are running low on memory resources
|
||||||
|
const auto required_descriptors = rsx::method_registers.current_draw_clause.pass_count();
|
||||||
|
verify(HERE), required_descriptors < DESCRIPTOR_MAX_DRAW_CALLS;
|
||||||
|
if ((required_descriptors + m_current_frame->used_descriptors) > DESCRIPTOR_MAX_DRAW_CALLS)
|
||||||
|
{
|
||||||
|
//No need to stall if we have more than one frame queue anyway
|
||||||
|
flush_command_queue();
|
||||||
|
|
||||||
|
CHECK_RESULT(vkResetDescriptorPool(*m_device, m_current_frame->descriptor_pool, 0));
|
||||||
|
m_current_frame->used_descriptors = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDescriptorSet VKGSRender::allocate_descriptor_set()
|
||||||
|
{
|
||||||
|
verify(HERE), m_current_frame->used_descriptors < DESCRIPTOR_MAX_DRAW_CALLS;
|
||||||
|
|
||||||
|
VkDescriptorSetAllocateInfo alloc_info = {};
|
||||||
|
alloc_info.descriptorPool = m_current_frame->descriptor_pool;
|
||||||
|
alloc_info.descriptorSetCount = 1;
|
||||||
|
alloc_info.pSetLayouts = &descriptor_layouts;
|
||||||
|
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
|
|
||||||
|
VkDescriptorSet new_descriptor_set;
|
||||||
|
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &new_descriptor_set));
|
||||||
|
m_current_frame->used_descriptors++;
|
||||||
|
|
||||||
|
return new_descriptor_set;
|
||||||
|
}
|
||||||
|
|
||||||
void VKGSRender::begin()
|
void VKGSRender::begin()
|
||||||
{
|
{
|
||||||
rsx::thread::begin();
|
rsx::thread::begin();
|
||||||
|
@ -1042,29 +1074,7 @@ void VKGSRender::begin()
|
||||||
if (!framebuffer_status_valid)
|
if (!framebuffer_status_valid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Ease resource pressure if the number of draw calls becomes too high or we are running low on memory resources
|
|
||||||
if (m_current_frame->used_descriptors >= DESCRIPTOR_MAX_DRAW_CALLS)
|
|
||||||
{
|
|
||||||
//No need to stall if we have more than one frame queue anyway
|
|
||||||
flush_command_queue();
|
|
||||||
|
|
||||||
CHECK_RESULT(vkResetDescriptorPool(*m_device, m_current_frame->descriptor_pool, 0));
|
|
||||||
m_current_frame->used_descriptors = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_heap_status();
|
check_heap_status();
|
||||||
|
|
||||||
VkDescriptorSetAllocateInfo alloc_info = {};
|
|
||||||
alloc_info.descriptorPool = m_current_frame->descriptor_pool;
|
|
||||||
alloc_info.descriptorSetCount = 1;
|
|
||||||
alloc_info.pSetLayouts = &descriptor_layouts;
|
|
||||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
||||||
|
|
||||||
VkDescriptorSet new_descriptor_set;
|
|
||||||
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &new_descriptor_set));
|
|
||||||
|
|
||||||
m_current_frame->descriptor_set = new_descriptor_set;
|
|
||||||
m_current_frame->used_descriptors++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKGSRender::update_draw_state()
|
void VKGSRender::update_draw_state()
|
||||||
|
@ -1207,25 +1217,36 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Vertex env update will change information in the descriptor set
|
||||||
|
// Make a copy for the next draw call
|
||||||
|
// TODO: Restructure program to allow use of push constants when possible
|
||||||
|
// NOTE: AMD has insuffecient push constants buffer memory which is unfortunate
|
||||||
|
VkDescriptorSet new_descriptor_set = allocate_descriptor_set();
|
||||||
|
std::array<VkCopyDescriptorSet, VK_NUM_DESCRIPTOR_BINDINGS> copy_set;
|
||||||
|
|
||||||
|
for (u32 n = 0; n < VK_NUM_DESCRIPTOR_BINDINGS; ++n)
|
||||||
|
{
|
||||||
|
copy_set[n] =
|
||||||
|
{
|
||||||
|
VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, // sType
|
||||||
|
nullptr, // pNext
|
||||||
|
m_current_frame->descriptor_set, // srcSet
|
||||||
|
n, // srcBinding
|
||||||
|
0u, // srcArrayElement
|
||||||
|
new_descriptor_set, // dstSet
|
||||||
|
n, // dstBinding
|
||||||
|
0u, // dstArrayElement
|
||||||
|
1u // descriptorCount
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(*m_device, 0, 0, VK_NUM_DESCRIPTOR_BINDINGS, copy_set.data());
|
||||||
|
m_current_frame->descriptor_set = new_descriptor_set;
|
||||||
|
|
||||||
if (persistent_buffer != old_persistent_buffer || volatile_buffer != old_volatile_buffer)
|
if (persistent_buffer != old_persistent_buffer || volatile_buffer != old_volatile_buffer)
|
||||||
{
|
{
|
||||||
/* VkDescriptorSetAllocateInfo alloc_info = {};
|
// Rare event, we need to actually change the descriptors
|
||||||
alloc_info.descriptorPool = m_current_frame->descriptor_pool;
|
update_descriptors = true;
|
||||||
alloc_info.descriptorSetCount = 1;
|
|
||||||
alloc_info.pSetLayouts = &descriptor_layouts;
|
|
||||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
||||||
|
|
||||||
VkDescriptorSet new_descriptor_set;
|
|
||||||
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &new_descriptor_set));
|
|
||||||
|
|
||||||
VkCopyDescriptorSet copy = {};
|
|
||||||
copy.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
|
|
||||||
copy
|
|
||||||
|
|
||||||
m_current_frame->descriptor_set = new_descriptor_set;
|
|
||||||
m_current_frame->used_descriptors++;
|
|
||||||
|
|
||||||
update_descriptors = true;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1236,10 +1257,11 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||||
{
|
{
|
||||||
m_program->bind_uniform(persistent_buffer, vk::glsl::program_input_type::input_type_texel_buffer, "persistent_input_stream", m_current_frame->descriptor_set);
|
m_program->bind_uniform(persistent_buffer, vk::glsl::program_input_type::input_type_texel_buffer, "persistent_input_stream", m_current_frame->descriptor_set);
|
||||||
m_program->bind_uniform(volatile_buffer, vk::glsl::program_input_type::input_type_texel_buffer, "volatile_input_stream", m_current_frame->descriptor_set);
|
m_program->bind_uniform(volatile_buffer, vk::glsl::program_input_type::input_type_texel_buffer, "volatile_input_stream", m_current_frame->descriptor_set);
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &m_current_frame->descriptor_set, 0, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind the new set of descriptors for use with this draw call
|
||||||
|
vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &m_current_frame->descriptor_set, 0, nullptr);
|
||||||
|
|
||||||
//std::chrono::time_point<steady_clock> draw_start = steady_clock::now();
|
//std::chrono::time_point<steady_clock> draw_start = steady_clock::now();
|
||||||
//m_setup_time += std::chrono::duration_cast<std::chrono::microseconds>(draw_start - vertex_end).count();
|
//m_setup_time += std::chrono::duration_cast<std::chrono::microseconds>(draw_start - vertex_end).count();
|
||||||
|
|
||||||
|
@ -1539,6 +1561,10 @@ void VKGSRender::end()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate descriptor set
|
||||||
|
check_descriptors();
|
||||||
|
m_current_frame->descriptor_set = allocate_descriptor_set();
|
||||||
|
|
||||||
// Load program execution environment
|
// Load program execution environment
|
||||||
load_program_env();
|
load_program_env();
|
||||||
|
|
||||||
|
|
|
@ -424,6 +424,9 @@ private:
|
||||||
|
|
||||||
void check_heap_status();
|
void check_heap_status();
|
||||||
|
|
||||||
|
void check_descriptors();
|
||||||
|
VkDescriptorSet allocate_descriptor_set();
|
||||||
|
|
||||||
vk::vertex_upload_info upload_vertex_data();
|
vk::vertex_upload_info upload_vertex_data();
|
||||||
|
|
||||||
bool load_program();
|
bool load_program();
|
||||||
|
|
|
@ -257,6 +257,17 @@ namespace rsx
|
||||||
return (draw_command_ranges.empty() && inline_vertex_array.empty());
|
return (draw_command_ranges.empty() && inline_vertex_array.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 pass_count() const
|
||||||
|
{
|
||||||
|
if (draw_command_ranges.empty())
|
||||||
|
{
|
||||||
|
verify(HERE), !inline_vertex_array.empty();
|
||||||
|
return 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (u32)draw_command_ranges.size();
|
||||||
|
}
|
||||||
|
|
||||||
void reset(rsx::primitive_type type)
|
void reset(rsx::primitive_type type)
|
||||||
{
|
{
|
||||||
current_range_index = -1u;
|
current_range_index = -1u;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue