WIP separate transfer queue/command?

per-device-font
jackun 2 years ago
parent 41ce693e7a
commit fea9f3475e
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -63,12 +63,12 @@ namespace MangoHud { namespace GL {
#endif
struct vk_image {
bool uploaded;
VkImage image;
VkImageView image_view;
VkDeviceMemory mem;
VkBuffer buffer;
VkDeviceMemory buffer_mem;
uint32_t width, height;
size_t size;
bool uploaded;
};
/* Mapped from VkInstace/VkPhysicalDevice */
@ -97,9 +97,11 @@ struct device_data {
VkPhysicalDeviceProperties properties;
struct queue_data *graphic_queue;
struct queue_data *transfer_queue;
std::vector<struct queue_data *> queues;
VkCommandPool command_pool;
VkDescriptorPool descriptor_pool;
VkDescriptorSetLayout descriptor_layout;
VkDescriptorSet descriptor_set;
@ -315,6 +317,15 @@ static VkDescriptorSet alloc_descriptor_set(const struct device_data *device_dat
static void setup_device_pipeline(struct device_data *device_data)
{
/* Command buffer pool for transfers */
VkCommandPoolCreateInfo cmd_buffer_pool_info = {};
cmd_buffer_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cmd_buffer_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
cmd_buffer_pool_info.queueFamilyIndex = device_data->transfer_queue->family_index;
VK_CHECK(device_data->vtable.CreateCommandPool(device_data->device,
&cmd_buffer_pool_info,
NULL, &device_data->command_pool));
/* Sampler */
VkSamplerCreateInfo sampler_info = {};
sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
@ -360,7 +371,6 @@ static void setup_device_pipeline(struct device_data *device_data)
/* Descriptor set */
device_data->descriptor_set = alloc_descriptor_set(device_data);
}
static struct queue_data *new_queue_data(VkQueue queue,
@ -375,9 +385,11 @@ static struct queue_data *new_queue_data(VkQueue queue,
data->family_index = family_index;
map_object(HKEY(data->queue), data);
SPDLOG_DEBUG("queue: 0x{:02x}", data->flags);
if (data->flags & VK_QUEUE_GRAPHICS_BIT)
device_data->graphic_queue = data;
if (data->flags & VK_QUEUE_TRANSFER_BIT)
device_data->transfer_queue = data;
return data;
}
@ -694,10 +706,10 @@ static void create_image(struct device_data *device_data,
uint32_t width,
uint32_t height,
VkFormat format,
VkImage& image,
VkDeviceMemory& image_mem,
VkImageView& image_view)
vk_image& image)
{
image.width = width;
image.height = height;
VkImageCreateInfo image_info = {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@ -714,10 +726,10 @@ static void create_image(struct device_data *device_data,
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VK_CHECK(device_data->vtable.CreateImage(device_data->device, &image_info,
NULL, &image));
NULL, &image.image));
VkMemoryRequirements font_image_req;
device_data->vtable.GetImageMemoryRequirements(device_data->device,
image, &font_image_req);
image.image, &font_image_req);
VkMemoryAllocateInfo image_alloc_info = {};
image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
image_alloc_info.allocationSize = font_image_req.size;
@ -725,22 +737,82 @@ static void create_image(struct device_data *device_data,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
font_image_req.memoryTypeBits);
VK_CHECK(device_data->vtable.AllocateMemory(device_data->device, &image_alloc_info,
NULL, &image_mem));
NULL, &image.mem));
VK_CHECK(device_data->vtable.BindImageMemory(device_data->device,
image,
image_mem, 0));
image.image,
image.mem, 0));
/* Font image view */
VkImageViewCreateInfo view_info = {};
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.image = image;
view_info.image = image.image;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.format = format;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.layerCount = 1;
VK_CHECK(device_data->vtable.CreateImageView(device_data->device, &view_info,
NULL, &image_view));
NULL, &image.image_view));
}
static void upload_font_image(struct device_data *device_data, vk_image *img, void *pixels, size_t upload_size)
{
if (img->uploaded)
return;
auto start = Clock::now();
VkCommandBuffer cmd_buffer;
VkCommandBufferAllocateInfo cmd_buffer_info = {};
cmd_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmd_buffer_info.commandPool = device_data->command_pool;
cmd_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmd_buffer_info.commandBufferCount = 1;
VK_CHECK(device_data->vtable.AllocateCommandBuffers(device_data->device,
&cmd_buffer_info,
&cmd_buffer));
VK_CHECK(device_data->set_device_loader_data(device_data->device,
cmd_buffer));
VkCommandBufferBeginInfo buffer_begin_info = {};
buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
VK_CHECK(device_data->vtable.BeginCommandBuffer(cmd_buffer, &buffer_begin_info));
VkBuffer buffer;
VkDeviceMemory buffer_mem;
upload_image_data(device_data, cmd_buffer, pixels, upload_size, img->width, img->height,
buffer, buffer_mem, device_data->font_img.image);
device_data->vtable.EndCommandBuffer(cmd_buffer);
VkFence fence;
VkFenceCreateInfo fence_info = {};
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
VK_CHECK(device_data->vtable.CreateFence(device_data->device,
&fence_info,
NULL,
&fence));
VkSubmitInfo submit_info = {};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &cmd_buffer;
SPDLOG_DEBUG("transfer queue: {}, {}", (void*)device_data->transfer_queue->queue, (void*)device_data->graphic_queue->queue);
VkResult r;
VK_CHECK(r = device_data->vtable.QueueSubmit(device_data->transfer_queue->queue, 1, &submit_info, fence));
if (r == VK_SUCCESS)
VK_CHECK(device_data->vtable.WaitForFences(device_data->device, 1, &fence, VK_TRUE, UINT64_MAX));
device_data->vtable.FreeCommandBuffers(device_data->device, device_data->command_pool, 1, &cmd_buffer);
device_data->vtable.DestroyFence(device_data->device, fence, NULL);
device_data->vtable.DestroyBuffer(device_data->device, buffer, NULL);
device_data->vtable.FreeMemory(device_data->device, buffer_mem, NULL);
img->uploaded = true;
auto dur = Clock::now() - start;
auto dur_us = std::chrono::duration_cast<std::chrono::microseconds>(dur).count();
SPDLOG_DEBUG("upload duration: {} us, {} bytes, {:0.02f} MiB/s", dur_us, upload_size, upload_size/(dur_us/1e6f)/(1024*1024));
}
static void check_fonts(struct device_data* device_data)
@ -750,8 +822,14 @@ static void check_fonts(struct device_data* device_data)
return;
std::unique_lock<std::mutex> lk(device_data->font_mutex);
if (params.font_params_hash == device_data->font_params_hash)
return;
SPDLOG_DEBUG("Recreating font image");
device_data->font_params_hash = params.font_params_hash;
create_fonts(device_data->font_atlas, params, device_data->font_alt, device_data->font_text);
unsigned char* pixels;
int width, height;
device_data->font_atlas->GetTexDataAsAlpha8(&pixels, &width, &height);
@ -759,15 +837,15 @@ static void check_fonts(struct device_data* device_data)
// wait for rendering to complete, if any
VK_CHECK(device_data->vtable.DeviceWaitIdle(device_data->device));
shutdown_device_font(device_data);
create_image(device_data, width, height, VK_FORMAT_R8_UNORM, device_data->font_img.image, device_data->font_img.mem, device_data->font_img.image_view);
create_image(device_data, width, height, VK_FORMAT_R8_UNORM, device_data->font_img);
device_data->font_img.uploaded = false;
device_data->font_params_hash = params.font_params_hash;
SPDLOG_DEBUG("Default font tex size: {}x{}px", width, height);
SPDLOG_DEBUG("Update font image descriptor {}", (void*)device_data->descriptor_set);
update_image_descriptor(device_data, device_data->font_img.image_view, device_data->descriptor_set);
device_data->font_atlas->SetTexID((ImTextureID)device_data->descriptor_set);
// std::thread(upload_font_image, device_data, &device_data->font_img, pixels, width * height * 1 * sizeof(char)).detach();
upload_font_image(device_data, &device_data->font_img, pixels, width * height * 1 * sizeof(char));
}
static void check_fonts(struct swapchain_data* data)
@ -781,23 +859,6 @@ static void check_fonts(struct swapchain_data* data)
}
}
static void ensure_swapchain_fonts(struct swapchain_data *data,
VkCommandBuffer command_buffer)
{
struct device_data *device_data = data->device;
if (device_data->font_img.uploaded)
return;
device_data->font_img.uploaded = true;
unsigned char* pixels;
int width, height;
device_data->font_atlas->GetTexDataAsAlpha8(&pixels, &width, &height);
size_t upload_size = width * height * 1 * sizeof(char);
upload_image_data(device_data, command_buffer, pixels, upload_size, width, height,
device_data->font_img.buffer, device_data->font_img.buffer_mem, device_data->font_img.image);
}
static void CreateOrResizeBuffer(struct device_data *data,
VkBuffer *buffer,
VkDeviceMemory *buffer_memory,
@ -863,7 +924,7 @@ static struct overlay_draw *render_swapchain_display(struct swapchain_data *data
device_data->vtable.BeginCommandBuffer(draw->command_buffer, &buffer_begin_info);
ensure_swapchain_fonts(data, draw->command_buffer);
// ensure_swapchain_fonts(data->device, draw->command_buffer);
/* Bounce the image to display back to color attachment layout for
* rendering on top of it.
@ -1416,8 +1477,8 @@ static void shutdown_device_font(struct device_data *device_data)
device_data->vtable.DestroyImage(device_data->device, device_data->font_img.image, NULL);
device_data->vtable.FreeMemory(device_data->device, device_data->font_img.mem, NULL);
device_data->vtable.DestroyBuffer(device_data->device, device_data->font_img.buffer, NULL);
device_data->vtable.FreeMemory(device_data->device, device_data->font_img.buffer_mem, NULL);
// device_data->vtable.DestroyBuffer(device_data->device, device_data->font_img.buffer, NULL);
// device_data->vtable.FreeMemory(device_data->device, device_data->font_img.buffer_mem, NULL);
device_data->font_img = {};
}
@ -1826,6 +1887,7 @@ static void overlay_DestroyDevice(
device_data->vtable.DestroySampler(device_data->device, device_data->sampler, NULL);
device_data->vtable.DestroyCommandPool(device_data->device, device_data->command_pool, NULL);
device_data->vtable.DestroyDevice(device, pAllocator);
destroy_device_data(device_data);
}

Loading…
Cancel
Save