mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-09-29 15:31:14 +00:00
vk: Implement basic descriptor updates batching
This commit is contained in:
parent
24642a4c18
commit
4752c4014b
@ -162,13 +162,13 @@ namespace vk
|
||||
alloc_info.pSetLayouts = &m_descriptor_layout;
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(*g_render_device, &alloc_info, &m_descriptor_set));
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(*g_render_device, &alloc_info, m_descriptor_set.ptr()));
|
||||
m_used_descriptors++;
|
||||
|
||||
bind_resources();
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, m_program->pipeline);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline_layout, 0, 1, &m_descriptor_set, 0, nullptr);
|
||||
m_descriptor_set.bind(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline_layout);
|
||||
}
|
||||
|
||||
void compute_task::run(VkCommandBuffer cmd, u32 invocations_x, u32 invocations_y, u32 invocations_z)
|
||||
|
@ -20,7 +20,7 @@ namespace vk
|
||||
std::unique_ptr<vk::buffer> m_param_buffer;
|
||||
|
||||
vk::descriptor_pool m_descriptor_pool;
|
||||
VkDescriptorSet m_descriptor_set = nullptr;
|
||||
descriptor_set m_descriptor_set;
|
||||
VkDescriptorSetLayout m_descriptor_layout = nullptr;
|
||||
VkPipelineLayout m_pipeline_layout = nullptr;
|
||||
u32 m_used_descriptors = 0;
|
||||
|
@ -791,28 +791,27 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
else if (persistent_buffer != old_persistent_buffer || volatile_buffer != old_volatile_buffer)
|
||||
{
|
||||
// Need to update descriptors; make a copy for the next draw
|
||||
VkDescriptorSet new_descriptor_set = allocate_descriptor_set();
|
||||
std::vector<VkCopyDescriptorSet> copy_set(binding_table.total_descriptor_bindings);
|
||||
VkDescriptorSet previous_set = m_current_frame->descriptor_set.value();
|
||||
m_current_frame->descriptor_set = allocate_descriptor_set();
|
||||
std::vector<VkCopyDescriptorSet> copy_cmds(binding_table.total_descriptor_bindings);
|
||||
|
||||
for (u32 n = 0; n < binding_table.total_descriptor_bindings; ++n)
|
||||
{
|
||||
copy_set[n] =
|
||||
copy_cmds[n] =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, // sType
|
||||
nullptr, // pNext
|
||||
m_current_frame->descriptor_set, // srcSet
|
||||
previous_set, // srcSet
|
||||
n, // srcBinding
|
||||
0u, // srcArrayElement
|
||||
new_descriptor_set, // dstSet
|
||||
m_current_frame->descriptor_set.value(), // dstSet
|
||||
n, // dstBinding
|
||||
0u, // dstArrayElement
|
||||
1u // descriptorCount
|
||||
};
|
||||
}
|
||||
|
||||
vkUpdateDescriptorSets(*m_device, 0, 0, binding_table.total_descriptor_bindings, copy_set.data());
|
||||
m_current_frame->descriptor_set = new_descriptor_set;
|
||||
|
||||
m_current_frame->descriptor_set.push(copy_cmds);
|
||||
update_descriptors = true;
|
||||
}
|
||||
|
||||
@ -866,8 +865,7 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
}
|
||||
|
||||
// Bind the new set of descriptors for use with this draw call
|
||||
vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline_layout, 0, 1, &m_current_frame->descriptor_set, 0, nullptr);
|
||||
|
||||
m_current_frame->descriptor_set.bind(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline_layout);
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
|
||||
if (!upload_info.index_info)
|
||||
|
@ -196,8 +196,8 @@ namespace vk
|
||||
{
|
||||
VkSemaphore acquire_signal_semaphore = VK_NULL_HANDLE;
|
||||
VkSemaphore present_wait_semaphore = VK_NULL_HANDLE;
|
||||
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
|
||||
|
||||
vk::descriptor_set descriptor_set;
|
||||
vk::descriptor_pool descriptor_pool;
|
||||
u32 used_descriptors = 0;
|
||||
|
||||
@ -227,7 +227,7 @@ namespace vk
|
||||
{
|
||||
present_wait_semaphore = other.present_wait_semaphore;
|
||||
acquire_signal_semaphore = other.acquire_signal_semaphore;
|
||||
descriptor_set = other.descriptor_set;
|
||||
descriptor_set.swap(other.descriptor_set);
|
||||
descriptor_pool = other.descriptor_pool;
|
||||
used_descriptors = other.used_descriptors;
|
||||
flags = other.flags;
|
||||
|
@ -235,7 +235,7 @@ namespace vk
|
||||
alloc_info.pSetLayouts = &m_descriptor_layout;
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &m_descriptor_set));
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, m_descriptor_set.ptr()));
|
||||
m_used_descriptors++;
|
||||
|
||||
if (!m_sampler && !src.empty())
|
||||
@ -256,7 +256,7 @@ namespace vk
|
||||
}
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, program->pipeline);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, &m_descriptor_set, 0, nullptr);
|
||||
m_descriptor_set.bind(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout);
|
||||
|
||||
VkBuffer buffers = m_vao.heap->value;
|
||||
VkDeviceSize offsets = m_vao_offset;
|
||||
|
@ -44,7 +44,7 @@ namespace vk
|
||||
vk::glsl::shader m_fragment_shader;
|
||||
|
||||
vk::descriptor_pool m_descriptor_pool;
|
||||
VkDescriptorSet m_descriptor_set = nullptr;
|
||||
descriptor_set m_descriptor_set;
|
||||
VkDescriptorSetLayout m_descriptor_layout = nullptr;
|
||||
VkPipelineLayout m_pipeline_layout = nullptr;
|
||||
u32 m_used_descriptors = 0;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "VKProgramPipeline.h"
|
||||
#include "vkutils/descriptors.h"
|
||||
#include "vkutils/device.h"
|
||||
#include <string>
|
||||
|
||||
@ -158,7 +159,7 @@ namespace vk
|
||||
});
|
||||
}
|
||||
|
||||
void program::bind_uniform(const VkDescriptorImageInfo &image_descriptor, const std::string& uniform_name, VkDescriptorType type, VkDescriptorSet &descriptor_set)
|
||||
void program::bind_uniform(const VkDescriptorImageInfo &image_descriptor, const std::string& uniform_name, VkDescriptorType type, vk::descriptor_set &set)
|
||||
{
|
||||
for (const auto &uniform : uniforms[program_input_type::input_type_texture])
|
||||
{
|
||||
@ -168,7 +169,7 @@ namespace vk
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
|
||||
nullptr, // pNext
|
||||
descriptor_set, // dstSet
|
||||
VK_NULL_HANDLE, // dstSet
|
||||
uniform.location, // dstBinding
|
||||
0, // dstArrayElement
|
||||
1, // descriptorCount
|
||||
@ -178,7 +179,7 @@ namespace vk
|
||||
nullptr // pTexelBufferView
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
|
||||
set.push(descriptor_writer);
|
||||
attribute_location_mask |= (1ull << uniform.location);
|
||||
return;
|
||||
}
|
||||
@ -187,7 +188,7 @@ namespace vk
|
||||
rsx_log.notice("texture not found in program: %s", uniform_name.c_str());
|
||||
}
|
||||
|
||||
void program::bind_uniform(const VkDescriptorImageInfo & image_descriptor, int texture_unit, ::glsl::program_domain domain, VkDescriptorSet &descriptor_set, bool is_stencil_mirror)
|
||||
void program::bind_uniform(const VkDescriptorImageInfo & image_descriptor, int texture_unit, ::glsl::program_domain domain, vk::descriptor_set &set, bool is_stencil_mirror)
|
||||
{
|
||||
ensure(domain != ::glsl::program_domain::glsl_compute_program);
|
||||
|
||||
@ -207,7 +208,7 @@ namespace vk
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
|
||||
nullptr, // pNext
|
||||
descriptor_set, // dstSet
|
||||
VK_NULL_HANDLE, // dstSet
|
||||
binding, // dstBinding
|
||||
0, // dstArrayElement
|
||||
1, // descriptorCount
|
||||
@ -217,7 +218,7 @@ namespace vk
|
||||
nullptr // pTexelBufferView
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
|
||||
set.push(descriptor_writer);
|
||||
attribute_location_mask |= (1ull << binding);
|
||||
return;
|
||||
}
|
||||
@ -225,18 +226,18 @@ namespace vk
|
||||
rsx_log.notice("texture not found in program: %stex%u", (domain == ::glsl::program_domain::glsl_vertex_program)? "v" : "", texture_unit);
|
||||
}
|
||||
|
||||
void program::bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorSet &descriptor_set)
|
||||
void program::bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, vk::descriptor_set &set)
|
||||
{
|
||||
bind_buffer(buffer_descriptor, binding_point, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptor_set);
|
||||
bind_buffer(buffer_descriptor, binding_point, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, set);
|
||||
}
|
||||
|
||||
void program::bind_uniform(const VkBufferView &buffer_view, u32 binding_point, VkDescriptorSet &descriptor_set)
|
||||
void program::bind_uniform(const VkBufferView &buffer_view, u32 binding_point, vk::descriptor_set &set)
|
||||
{
|
||||
const VkWriteDescriptorSet descriptor_writer =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
|
||||
nullptr, // pNext
|
||||
descriptor_set, // dstSet
|
||||
VK_NULL_HANDLE, // dstSet
|
||||
binding_point, // dstBinding
|
||||
0, // dstArrayElement
|
||||
1, // descriptorCount
|
||||
@ -246,17 +247,17 @@ namespace vk
|
||||
&buffer_view // pTexelBufferView
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
|
||||
set.push(descriptor_writer);
|
||||
attribute_location_mask |= (1ull << binding_point);
|
||||
}
|
||||
|
||||
void program::bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, VkDescriptorSet &descriptor_set)
|
||||
void program::bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, vk::descriptor_set &set)
|
||||
{
|
||||
for (const auto &uniform : uniforms[type])
|
||||
{
|
||||
if (uniform.name == binding_name)
|
||||
{
|
||||
bind_uniform(buffer_view, uniform.location, descriptor_set);
|
||||
bind_uniform(buffer_view, uniform.location, set);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -264,13 +265,13 @@ namespace vk
|
||||
rsx_log.notice("vertex buffer not found in program: %s", binding_name.c_str());
|
||||
}
|
||||
|
||||
void program::bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorType type, VkDescriptorSet &descriptor_set)
|
||||
void program::bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorType type, vk::descriptor_set &set)
|
||||
{
|
||||
const VkWriteDescriptorSet descriptor_writer =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
|
||||
nullptr, // pNext
|
||||
descriptor_set, // dstSet
|
||||
VK_NULL_HANDLE, // dstSet
|
||||
binding_point, // dstBinding
|
||||
0, // dstArrayElement
|
||||
1, // descriptorCount
|
||||
@ -280,7 +281,7 @@ namespace vk
|
||||
nullptr // pTexelBufferView
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
|
||||
set.push(descriptor_writer);
|
||||
attribute_location_mask |= (1ull << binding_point);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
#include "VulkanAPI.h"
|
||||
#include "VKCommonDecompiler.h"
|
||||
#include "../Program/GLSLTypes.h"
|
||||
|
||||
#include "vkutils/descriptors.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -99,14 +100,12 @@ namespace vk
|
||||
program& link();
|
||||
|
||||
bool has_uniform(program_input_type type, const std::string &uniform_name);
|
||||
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, const std::string &uniform_name, VkDescriptorType type, VkDescriptorSet &descriptor_set);
|
||||
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, int texture_unit, ::glsl::program_domain domain, VkDescriptorSet &descriptor_set, bool is_stencil_mirror = false);
|
||||
void bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorSet &descriptor_set);
|
||||
void bind_uniform(const VkBufferView &buffer_view, u32 binding_point, VkDescriptorSet &descriptor_set);
|
||||
void bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, VkDescriptorSet &descriptor_set);
|
||||
|
||||
void bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorType type, VkDescriptorSet &descriptor_set);
|
||||
void bind_descriptor_set(const VkCommandBuffer cmd, VkDescriptorSet descriptor_set);
|
||||
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, const std::string &uniform_name, VkDescriptorType type, vk::descriptor_set &set);
|
||||
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, int texture_unit, ::glsl::program_domain domain, vk::descriptor_set &set, bool is_stencil_mirror = false);
|
||||
void bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, vk::descriptor_set &set);
|
||||
void bind_uniform(const VkBufferView &buffer_view, u32 binding_point, vk::descriptor_set &set);
|
||||
void bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, vk::descriptor_set &set);
|
||||
void bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorType type, vk::descriptor_set &set);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -508,7 +508,7 @@ namespace vk
|
||||
return program.release();
|
||||
}
|
||||
|
||||
void shader_interpreter::update_fragment_textures(const std::array<VkDescriptorImageInfo, 68>& sampled_images, VkDescriptorSet descriptor_set)
|
||||
void shader_interpreter::update_fragment_textures(const std::array<VkDescriptorImageInfo, 68>& sampled_images, vk::descriptor_set &set)
|
||||
{
|
||||
const VkDescriptorImageInfo* texture_ptr = sampled_images.data();
|
||||
for (u32 i = 0, binding = m_fragment_textures_start; i < 4; ++i, ++binding, texture_ptr += 16)
|
||||
@ -517,7 +517,7 @@ namespace vk
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
|
||||
nullptr, // pNext
|
||||
descriptor_set, // dstSet
|
||||
VK_NULL_HANDLE, // dstSet
|
||||
binding, // dstBinding
|
||||
0, // dstArrayElement
|
||||
16, // descriptorCount
|
||||
@ -527,7 +527,7 @@ namespace vk
|
||||
nullptr // pTexelBufferView
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
|
||||
set.push(descriptor_writer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ namespace vk
|
||||
u32 get_vertex_instruction_location() const;
|
||||
u32 get_fragment_instruction_location() const;
|
||||
|
||||
void update_fragment_textures(const std::array<VkDescriptorImageInfo, 68>& sampled_images, VkDescriptorSet descriptor_set);
|
||||
void update_fragment_textures(const std::array<VkDescriptorImageInfo, 68>& sampled_images, vk::descriptor_set &set);
|
||||
VkDescriptorSet allocate_descriptor_set();
|
||||
};
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace vk
|
||||
vk::glsl::shader m_fragment_shader;
|
||||
|
||||
vk::descriptor_pool m_descriptor_pool;
|
||||
VkDescriptorSet m_descriptor_set = nullptr;
|
||||
vk::descriptor_set m_descriptor_set;
|
||||
VkDescriptorSetLayout m_descriptor_layout = nullptr;
|
||||
VkPipelineLayout m_pipeline_layout = nullptr;
|
||||
u32 m_used_descriptors = 0;
|
||||
@ -213,7 +213,7 @@ namespace vk
|
||||
alloc_info.pSetLayouts = &m_descriptor_layout;
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(device, &alloc_info, &m_descriptor_set));
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_set.ptr()));
|
||||
m_used_descriptors++;
|
||||
|
||||
float scale[] = { scale_x, scale_y };
|
||||
@ -236,7 +236,7 @@ namespace vk
|
||||
m_uniform_buffer_offset = (m_uniform_buffer_offset + 8192) % m_uniform_buffer_size;
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, &m_descriptor_set, 0, nullptr);
|
||||
m_descriptor_set.bind(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout);
|
||||
|
||||
VkDeviceSize zero = 0;
|
||||
vkCmdBindVertexBuffers(cmd, 0, 1, &m_vertex_buffer->value, &zero);
|
||||
|
@ -53,4 +53,143 @@ namespace vk
|
||||
m_current_pool_handle = m_device_pools[m_current_pool_index];
|
||||
CHECK_RESULT(vkResetDescriptorPool(*m_owner, m_current_pool_handle, flags));
|
||||
}
|
||||
|
||||
descriptor_set::descriptor_set(VkDescriptorSet set)
|
||||
{
|
||||
flush();
|
||||
init();
|
||||
m_handle = set;
|
||||
}
|
||||
|
||||
descriptor_set::descriptor_set()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void descriptor_set::init()
|
||||
{
|
||||
if (m_image_info_pool.capacity() == 0)
|
||||
{
|
||||
m_image_info_pool.reserve(max_cache_size + 16);
|
||||
m_buffer_view_pool.reserve(max_cache_size + 16);
|
||||
m_buffer_info_pool.reserve(max_cache_size + 16);
|
||||
}
|
||||
}
|
||||
|
||||
VkBufferView* descriptor_set::dup(const VkBufferView* in)
|
||||
{
|
||||
if (!in) return nullptr;
|
||||
|
||||
m_buffer_view_pool.push_back(*in);
|
||||
return &m_buffer_view_pool.back();
|
||||
}
|
||||
|
||||
VkDescriptorBufferInfo* descriptor_set::dup(const VkDescriptorBufferInfo* in)
|
||||
{
|
||||
if (!in) return nullptr;
|
||||
|
||||
m_buffer_info_pool.push_back(*in);
|
||||
return &m_buffer_info_pool.back();
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo* descriptor_set::dup(const VkDescriptorImageInfo* in)
|
||||
{
|
||||
if (!in) return nullptr;
|
||||
|
||||
m_image_info_pool.push_back(*in);
|
||||
return &m_image_info_pool.back();
|
||||
}
|
||||
|
||||
void descriptor_set::swap(descriptor_set& other)
|
||||
{
|
||||
other.flush();
|
||||
flush();
|
||||
|
||||
std::swap(m_handle, other.m_handle);
|
||||
}
|
||||
|
||||
descriptor_set& descriptor_set::operator = (VkDescriptorSet set)
|
||||
{
|
||||
flush();
|
||||
m_handle = set;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VkDescriptorSet* descriptor_set::ptr()
|
||||
{
|
||||
// TODO: You shouldn't need this
|
||||
// ensure(m_handle == VK_NULL_HANDLE);
|
||||
return &m_handle;
|
||||
}
|
||||
|
||||
VkDescriptorSet descriptor_set::value() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
void descriptor_set::push(const VkWriteDescriptorSet& write_cmd)
|
||||
{
|
||||
if (m_pending_writes.size() >= max_cache_size)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
m_pending_writes.push_back(
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = m_handle,
|
||||
.dstBinding = write_cmd.dstBinding,
|
||||
.dstArrayElement = write_cmd.dstArrayElement,
|
||||
.descriptorCount = write_cmd.descriptorCount,
|
||||
.descriptorType = write_cmd.descriptorType,
|
||||
.pImageInfo = dup(write_cmd.pImageInfo),
|
||||
.pBufferInfo = dup(write_cmd.pBufferInfo),
|
||||
.pTexelBufferView = dup(write_cmd.pTexelBufferView)
|
||||
});
|
||||
}
|
||||
|
||||
void descriptor_set::push(std::vector<VkCopyDescriptorSet>& copy_cmd)
|
||||
{
|
||||
if (m_pending_copies.empty()) [[likely]]
|
||||
{
|
||||
m_pending_copies = std::move(copy_cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t old_size = m_pending_copies.size();
|
||||
const size_t new_size = copy_cmd.size() + old_size;
|
||||
m_pending_copies.resize(new_size);
|
||||
std::copy(copy_cmd.begin(), copy_cmd.end(), m_pending_copies.begin() + old_size);
|
||||
}
|
||||
}
|
||||
|
||||
void descriptor_set::bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout)
|
||||
{
|
||||
flush();
|
||||
vkCmdBindDescriptorSets(cmd, bind_point, layout, 0, 1, &m_handle, 0, nullptr);
|
||||
}
|
||||
|
||||
void descriptor_set::bind(const command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout)
|
||||
{
|
||||
bind(static_cast<VkCommandBuffer>(cmd), bind_point, layout);
|
||||
}
|
||||
|
||||
void descriptor_set::flush()
|
||||
{
|
||||
if (m_pending_writes.empty() && m_pending_copies.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto num_writes = ::size32(m_pending_writes);
|
||||
const auto num_copies = ::size32(m_pending_copies);
|
||||
vkUpdateDescriptorSets(*g_render_device, num_writes, m_pending_writes.data(), num_copies, m_pending_copies.data());
|
||||
|
||||
m_pending_writes.clear();
|
||||
m_pending_copies.clear();
|
||||
m_image_info_pool.clear();
|
||||
m_buffer_info_pool.clear();
|
||||
m_buffer_view_pool.clear();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../VulkanAPI.h"
|
||||
#include "commands.h"
|
||||
#include "device.h"
|
||||
|
||||
#include <vector>
|
||||
@ -9,12 +10,6 @@ namespace vk
|
||||
{
|
||||
class descriptor_pool
|
||||
{
|
||||
const vk::render_device* m_owner = nullptr;
|
||||
|
||||
std::vector<VkDescriptorPool> m_device_pools;
|
||||
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
|
||||
u32 m_current_pool_index = 0;
|
||||
|
||||
public:
|
||||
descriptor_pool() = default;
|
||||
~descriptor_pool() = default;
|
||||
@ -25,5 +20,54 @@ namespace vk
|
||||
|
||||
bool valid() const;
|
||||
operator VkDescriptorPool();
|
||||
|
||||
private:
|
||||
const vk::render_device* m_owner = nullptr;
|
||||
|
||||
std::vector<VkDescriptorPool> m_device_pools;
|
||||
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
|
||||
u32 m_current_pool_index = 0;
|
||||
};
|
||||
|
||||
class descriptor_set
|
||||
{
|
||||
const size_t max_cache_size = 16384;
|
||||
|
||||
VkBufferView* dup(const VkBufferView* in);
|
||||
VkDescriptorBufferInfo* dup(const VkDescriptorBufferInfo* in);
|
||||
VkDescriptorImageInfo* dup(const VkDescriptorImageInfo* in);
|
||||
|
||||
void flush();
|
||||
void init();
|
||||
|
||||
public:
|
||||
descriptor_set(VkDescriptorSet set);
|
||||
descriptor_set();
|
||||
~descriptor_set() = default;
|
||||
|
||||
descriptor_set(const descriptor_set&) = delete;
|
||||
|
||||
void swap(descriptor_set& other);
|
||||
descriptor_set& operator = (VkDescriptorSet set);
|
||||
|
||||
VkDescriptorSet* ptr();
|
||||
VkDescriptorSet value() const;
|
||||
void push(const VkWriteDescriptorSet& write_cmd);
|
||||
void push(std::vector<VkCopyDescriptorSet>& copy_cmd);
|
||||
|
||||
void bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
|
||||
void bind(const command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
|
||||
|
||||
private:
|
||||
VkDescriptorSet m_handle = VK_NULL_HANDLE;
|
||||
|
||||
std::vector<VkBufferView> m_buffer_view_pool;
|
||||
std::vector<VkDescriptorBufferInfo> m_buffer_info_pool;
|
||||
std::vector<VkDescriptorImageInfo> m_image_info_pool;
|
||||
|
||||
std::vector<VkWriteDescriptorSet> m_pending_writes;
|
||||
std::vector<VkCopyDescriptorSet> m_pending_copies;
|
||||
};
|
||||
|
||||
void flush_descriptor_updates();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user