Merge pull request #1603 from vlj/vulkan

vulkan: Remove buffer_deprecated completly.
This commit is contained in:
vlj 2016-03-21 00:45:02 +01:00
commit 1f500aad53
5 changed files with 44 additions and 217 deletions

View File

@ -435,6 +435,10 @@ VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan)
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &descriptor_sets));
null_buffer = std::make_unique<vk::buffer>(*m_device, 32, m_memory_type_mapping.host_visible_coherent, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0);
null_buffer_view = std::make_unique<vk::buffer_view>(*m_device, null_buffer->value, VK_FORMAT_R32_SFLOAT, 0, 32);
}
VKGSRender::~VKGSRender()
@ -459,8 +463,10 @@ VKGSRender::~VKGSRender()
m_index_buffer.release();
m_uniform_buffer.release();
m_attrib_buffers.release();
null_buffer.release();
null_buffer_view.release();
m_buffer_view_to_clean.clear();
for (auto &render_pass : m_render_passes)
if (render_pass)
@ -713,25 +719,13 @@ void VKGSRender::set_viewport()
void VKGSRender::on_init_thread()
{
GSRender::on_init_thread();
for (auto &attrib_buffer : m_attrib_buffers)
{
attrib_buffer.create((*m_device), 65536, VK_FORMAT_R8_UNORM, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
u8 *data = static_cast<u8*>(attrib_buffer.map(0, 65536));
memset(data, 0, 65536);
attrib_buffer.unmap();
}
m_attrib_ring_info.init(8 * RING_BUFFER_SIZE);
m_attrib_buffers.reset(new vk::buffer(*m_device, 8 * RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0));
}
void VKGSRender::on_exit()
{
m_texture_cache.destroy();
for (auto &attrib_buffer : m_attrib_buffers)
{
attrib_buffer.destroy();
}
}
void VKGSRender::clear_surface(u32 mask)
@ -1181,6 +1175,7 @@ void VKGSRender::flip(int buffer)
m_uniform_buffer_ring_info.m_get_pos = m_uniform_buffer_ring_info.get_current_put_pos_minus_one();
m_index_buffer_ring_info.m_get_pos = m_index_buffer_ring_info.get_current_put_pos_minus_one();
m_attrib_ring_info.m_get_pos = m_attrib_ring_info.get_current_put_pos_minus_one();
if (m_present_semaphore)
{
vkDestroySemaphore((*m_device), m_present_semaphore, nullptr);
@ -1191,6 +1186,8 @@ void VKGSRender::flip(int buffer)
m_texture_cache.merge_dirty_textures(m_rtts.invalidated_resources);
m_rtts.invalidated_resources.clear();
m_buffer_view_to_clean.clear();
m_draw_calls = 0;
dirty_frame = true;
m_frame->flip(m_context);

View File

@ -104,7 +104,8 @@ private:
rsx::surface_info m_surface;
vk::buffer_deprecated m_attrib_buffers[rsx::limits::vertex_count];
vk::data_heap m_attrib_ring_info;
std::unique_ptr<vk::buffer> m_attrib_buffers;
vk::texture_cache m_texture_cache;
rsx::vk_render_targets m_rtts;
@ -112,6 +113,9 @@ private:
vk::gpu_formats_support m_optimal_tiling_supported_formats;
vk::memory_type_mapping m_memory_type_mapping;
std::unique_ptr<vk::buffer> null_buffer;
std::unique_ptr<vk::buffer_view> null_buffer_view;
public:
//vk::fbo draw_fbo;
@ -146,6 +150,8 @@ private:
VkPipelineLayout pipeline_layout;
vk::descriptor_pool descriptor_pool;
std::vector<std::unique_ptr<vk::buffer_view> > m_buffer_view_to_clean;
u32 m_draw_calls = 0;
u8 m_draw_buffers_count = 0;

View File

@ -6,7 +6,6 @@ namespace vk
context *g_current_vulkan_ctx = nullptr;
render_device g_current_renderer;
buffer_deprecated g_null_buffer;
texture g_null_texture;
VkSampler g_null_sampler = nullptr;
@ -102,15 +101,6 @@ namespace vk
return callbacks;
}
VkBuffer null_buffer()
{
if (g_null_buffer.size())
return g_null_buffer;
g_null_buffer.create(g_current_renderer, 32, VK_FORMAT_R32_SFLOAT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
return g_null_buffer;
}
VkSampler null_sampler()
{
if (g_null_sampler)
@ -147,18 +137,8 @@ namespace vk
return g_null_image_view;
}
VkBufferView null_buffer_view()
{
if (g_null_buffer.size())
return g_null_buffer;
g_null_buffer.create(g_current_renderer, 32, VK_FORMAT_R32_SFLOAT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
return g_null_buffer;
}
void destroy_global_resources()
{
g_null_buffer.destroy();
g_null_texture.destroy();
if (g_null_sampler)

View File

@ -55,10 +55,8 @@ namespace vk
VkImageSubresource default_image_subresource();
VkImageSubresourceRange default_image_subresource_range();
VkBuffer null_buffer();
VkSampler null_sampler();
VkImageView null_image_view();
VkBufferView null_buffer_view();
void destroy_global_resources();
@ -464,167 +462,6 @@ namespace vk
VkDevice m_device;
};
class buffer_deprecated
{
VkBufferView m_view = nullptr;
VkBuffer m_buffer = nullptr;
VkMemoryRequirements m_memory_layout;
VkFormat m_internal_format = VK_FORMAT_UNDEFINED;
VkBufferUsageFlagBits m_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
VkBufferCreateFlags m_flags = 0;
vk::render_device *owner;
vk::memory_block_deprecated vram;
u64 m_size = 0;
bool viewable = false;
public:
buffer_deprecated() {}
~buffer_deprecated() {}
void create(vk::render_device &dev, u64 size, VkFormat format = VK_FORMAT_UNDEFINED, VkBufferUsageFlagBits usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferCreateFlags flags = 0)
{
if (m_buffer) throw EXCEPTION("Buffer create called on an existing buffer!");
owner = &dev;
VkBufferCreateInfo infos = {};
infos.size = size;
infos.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
infos.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
infos.flags = flags;
infos.usage = usage;
CHECK_RESULT(vkCreateBuffer(dev, &infos, nullptr, &m_buffer));
//Allocate vram for this buffer
vkGetBufferMemoryRequirements(dev, m_buffer, &m_memory_layout);
vram.allocate_from_pool(dev, m_memory_layout.size, m_memory_layout.memoryTypeBits);
viewable = !!(usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT));
//Bind buffer memory
vkBindBufferMemory(dev, m_buffer, vram, 0);
m_size = m_memory_layout.size;
m_usage = usage;
m_flags = flags;
set_format(format);
}
void *map(u32 offset, u64 size)
{
if (!vram.is_mappable()) return nullptr;
void *data = nullptr;
if (size == VK_WHOLE_SIZE)
size = m_memory_layout.size;
CHECK_RESULT(vkMapMemory((*owner), vram, offset, size, 0, &data));
return data;
}
void unmap()
{
vkUnmapMemory((*owner), vram);
}
void sub_data(u32 offset, u32 size, void *data)
{
//TODO: Synchronization
if (!data && (m_size < size))
{
vk::render_device *pdev = owner;
destroy();
create((*pdev), size, m_internal_format, m_usage, m_flags);
}
if (!data) return;
if ((offset + size) > m_size)
{
vk::render_device *tmp_owner = owner;
destroy();
create((*tmp_owner), size, m_internal_format, m_usage, m_flags);
}
u8 *dst = (u8*)map(offset, size);
u8 *src = (u8*)data;
memcpy(dst, src, size);
unmap();
}
void destroy()
{
if (!owner) return;
vkDestroyBufferView((*owner), m_view, nullptr);
vkDestroyBuffer((*owner), m_buffer, nullptr);
vram.destroy();
owner = nullptr;
m_view = nullptr;
m_buffer = nullptr;
m_internal_format = VK_FORMAT_UNDEFINED;
}
void set_format(VkFormat format)
{
if (m_internal_format == format || format == VK_FORMAT_UNDEFINED || !viewable)
return;
if (m_view)
{
vkDestroyBufferView((*owner), m_view, nullptr);
m_view = nullptr;
}
VkFormatProperties format_properties;
vk::physical_device dev = owner->gpu();
vkGetPhysicalDeviceFormatProperties(dev, format, &format_properties);
if (!(format_properties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))
throw EXCEPTION("Can't map view to requested format");
VkBufferViewCreateInfo view_info = {};
view_info.buffer = m_buffer;
view_info.format = format;
view_info.range = m_size;
view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
CHECK_RESULT(vkCreateBufferView((*owner), &view_info, nullptr, &m_view));
m_internal_format = format;
}
u64 size()
{
return m_size;
}
vk::render_device& get_owner()
{
return (*owner);
}
operator VkBuffer()
{
return m_buffer;
}
operator VkBufferView()
{
if (!viewable)
throw EXCEPTION("Invalid usage! Buffer cannot be viewed as texels.");
return m_view;
}
};
class framebuffer
{
VkFramebuffer m_vk_framebuffer = nullptr;
@ -1302,7 +1139,7 @@ namespace vk
struct bound_buffer
{
VkBufferView buffer_view = nullptr;
VkFormat format = VK_FORMAT_UNDEFINED;
VkBuffer buffer = nullptr;
u64 offset = 0;
u64 size = 0;

View File

@ -216,6 +216,20 @@ namespace vk
}
}
namespace
{
size_t alloc_and_copy(vk::buffer* buffer, vk::data_heap& data_heap_info, size_t size, std::function<void(gsl::span<gsl::byte> ptr)> copy_function)
{
size_t offset = data_heap_info.alloc<256>(size);
void* buf = buffer->map(offset, size);
gsl::span<gsl::byte> mapped_span = {reinterpret_cast<gsl::byte*>(buf), gsl::narrow<int>(size) };
copy_function(mapped_span);
buffer->unmap();
return offset;
}
}
std::tuple<VkPrimitiveTopology, bool, u32, VkDeviceSize, VkIndexType>
VKGSRender::upload_vertex_data()
{
@ -327,13 +341,10 @@ VKGSRender::upload_vertex_data()
throw EXCEPTION("Unknown base type %d", vertex_info.type);
}
auto &buffer = m_attrib_buffers[index];
size_t offset_in_attrib_buffer = alloc_and_copy(m_attrib_buffers.get(), m_attrib_ring_info, data_size, [&vertex_arrays_data, data_size](gsl::span<gsl::byte> ptr) { memcpy(ptr.data(), vertex_arrays_data.data(), data_size); });
buffer.sub_data(0, data_size, vertex_arrays_data.data());
buffer.set_format(format);
//Link texture to uniform location
m_program->bind_uniform(buffer, reg_table[index], descriptor_sets);
m_buffer_view_to_clean.push_back(std::make_unique<vk::buffer_view>(*m_device, m_attrib_buffers->value, format, offset_in_attrib_buffer, data_size));
m_program->bind_uniform(m_buffer_view_to_clean.back()->value, reg_table[index], descriptor_sets);
}
}
@ -417,11 +428,9 @@ VKGSRender::upload_vertex_data()
const VkFormat format = vk::get_suitable_vk_format(vertex_info.type, vertex_info.size);
const u32 data_size = vk::get_suitable_vk_size(vertex_info.type, vertex_info.size) * num_stored_verts;
auto &buffer = m_attrib_buffers[index];
buffer.sub_data(0, data_size, data_ptr);
buffer.set_format(format);
m_program->bind_uniform(buffer, reg_table[index], descriptor_sets);
size_t offset_in_attrib_buffer = alloc_and_copy(m_attrib_buffers.get(), m_attrib_ring_info, data_size, [data_ptr, data_size](gsl::span<gsl::byte> ptr) { memcpy(ptr.data(), data_ptr, data_size); });
m_buffer_view_to_clean.push_back(std::make_unique<vk::buffer_view>(*m_device, m_attrib_buffers->value, format, offset_in_attrib_buffer, data_size));
m_program->bind_uniform(m_buffer_view_to_clean.back()->value, reg_table[index], descriptor_sets);
}
else if (register_vertex_info[index].size > 0)
{
@ -455,12 +464,10 @@ VKGSRender::upload_vertex_data()
data_size = converted_buffer.size();
}
auto &buffer = m_attrib_buffers[index];
buffer.sub_data(0, data_size, data_ptr);
buffer.set_format(format);
m_program->bind_uniform(buffer, reg_table[index], descriptor_sets);
size_t offset_in_attrib_buffer = alloc_and_copy(m_attrib_buffers.get(), m_attrib_ring_info, data_size, [data_ptr, data_size](gsl::span<gsl::byte> ptr) { memcpy(ptr.data(), data_ptr, data_size); });
m_buffer_view_to_clean.push_back(std::make_unique<vk::buffer_view>(*m_device, m_attrib_buffers->value, format, offset_in_attrib_buffer, data_size));
m_program->bind_uniform(m_buffer_view_to_clean.back()->value, reg_table[index], descriptor_sets);
break;
}
default: