Skip to content

Commit

Permalink
images for vulkan
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas Adenis-Lamarre <[email protected]>
  • Loading branch information
nadenislamarre committed Dec 16, 2021
1 parent 7f5a81c commit 0e1a377
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 26 deletions.
38 changes: 26 additions & 12 deletions src/hud_elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,27 +618,34 @@ void HudElements::image(){

// load the image if needed
if(HUDElements.image_infos.loaded == false) {
unsigned maxwidth = HUDElements.params->width;
if(HUDElements.params->image_max_width != 0 && HUDElements.params->image_max_width < maxwidth) {
maxwidth = HUDElements.params->image_max_width;
}

HUDElements.image_infos.loaded = true;
if (!HUDElements.is_vulkan) {
unsigned maxwidth = HUDElements.params->width;
if(HUDElements.params->image_max_width != 0 && HUDElements.params->image_max_width < maxwidth) {
maxwidth = HUDElements.params->image_max_width;
}
if (HUDElements.is_vulkan) {
HUDElements.image_infos.vktexture = addTexture(value, &(HUDElements.image_infos.width), &(HUDElements.image_infos.height), maxwidth);
HUDElements.image_infos.valid = true;
} else {
HUDElements.image_infos.valid = GL_LoadTextureFromFile(value.c_str(),
&(HUDElements.image_infos.texture),
&(HUDElements.image_infos.width),
&(HUDElements.image_infos.height),
maxwidth);
spdlog::info("Image {} loaded ({}x{})", value, HUDElements.image_infos.width, HUDElements.image_infos.height);
}
spdlog::info("Image {} loaded ({}x{})", value, HUDElements.image_infos.width, HUDElements.image_infos.height);
}

// render the image
if(HUDElements.image_infos.valid) {
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Image((void*)(intptr_t)(HUDElements.image_infos.texture), ImVec2(HUDElements.image_infos.width, HUDElements.image_infos.height));
ImGui::PopFont();

if (HUDElements.is_vulkan) {
ImGui::Image(HUDElements.image_infos.vktexture, ImVec2(HUDElements.image_infos.width, HUDElements.image_infos.height));
} else {
ImGui::Image((void*)(intptr_t)(HUDElements.image_infos.texture), ImVec2(HUDElements.image_infos.width, HUDElements.image_infos.height));
}
}
}

Expand All @@ -648,19 +655,26 @@ void HudElements::background_image(){
// load the image if needed
if(HUDElements.background_image_infos.loaded == false) {
HUDElements.background_image_infos.loaded = true;
if (!HUDElements.is_vulkan) {
if (HUDElements.is_vulkan) {
HUDElements.background_image_infos.vktexture = addTexture(value, &(HUDElements.background_image_infos.width), &(HUDElements.background_image_infos.height), 0);
HUDElements.background_image_infos.valid = true;
} else {
HUDElements.background_image_infos.valid = GL_LoadTextureFromFile(value.c_str(),
&(HUDElements.background_image_infos.texture),
&(HUDElements.background_image_infos.width),
&(HUDElements.background_image_infos.height),
0);
spdlog::info("Image {} loaded ({}x{})", value, HUDElements.background_image_infos.width, HUDElements.background_image_infos.height);
}
spdlog::info("Image {} loaded ({}x{})", value, HUDElements.background_image_infos.width, HUDElements.background_image_infos.height);
}

// render the image
if(HUDElements.background_image_infos.valid) {
ImGui::GetBackgroundDrawList()->AddImage((void*)(intptr_t)(HUDElements.background_image_infos.texture), ImVec2(0, 0), ImVec2(HUDElements.background_image_infos.width, HUDElements.background_image_infos.height));
if (HUDElements.is_vulkan) {
ImGui::GetBackgroundDrawList()->AddImage(HUDElements.background_image_infos.vktexture, ImVec2(0, 0), ImVec2(HUDElements.background_image_infos.width, HUDElements.background_image_infos.height));
} else {
ImGui::GetBackgroundDrawList()->AddImage((void*)(intptr_t)(HUDElements.background_image_infos.texture), ImVec2(0, 0), ImVec2(HUDElements.background_image_infos.width, HUDElements.background_image_infos.height));
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/hud_elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct image_infos {
bool loaded;
bool valid;
GLuint texture;
ImTextureID vktexture;

image_infos() {
loaded = false;
Expand Down
3 changes: 2 additions & 1 deletion src/overlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,12 @@ void center_text(const std::string& text);
ImVec4 change_on_load_temp(LOAD_DATA& data, unsigned current);
float get_time_stat(void *_data, int _idx);
void stop_hw_updater();
ImTextureID addTexture(const std::string& filename, int* width, int* height, int maxwidth);
extern void control_client_check(struct device_data *device_data);
extern void process_control_socket(struct instance_data *instance_data);

#ifdef HAVE_DBUS
void render_mpris_metadata(overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing);
#endif

#endif //MANGOHUD_OVERLAY_H
#endif //MANGOHUD_OVERLAY_H
130 changes: 117 additions & 13 deletions src/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
#include "blacklist.h"
#include "pci_ids.h"

#include "stb_image.h"
#include "stb_image_resize.h"

float offset_x, offset_y, hudSpacing;
int hudFirstRow, hudSecondRow;
VkPhysicalDeviceDriverProperties driverProps = {};
Expand Down Expand Up @@ -104,6 +107,18 @@ struct overlay_draw {
VkDeviceSize index_buffer_size;
};

struct texture_info {
VkImage image;
VkImageView image_view;
VkDeviceMemory mem;
VkDescriptorSet descset;
VkBuffer upload_buffer;
VkDeviceMemory upload_buffer_mem;
std::string filename;
int maxwidth;
bool uploaded;
};

/* Mapped from VkSwapchainKHR */
struct swapchain_data {
struct device_data *device;
Expand Down Expand Up @@ -138,6 +153,9 @@ struct swapchain_data {
VkBuffer upload_font_buffer;
VkDeviceMemory upload_font_buffer_mem;

std::vector<struct texture_info> textures;
VkSampler texture_sampler;

/**/
ImGuiContext* imgui_context;
ImVec2 window_size;
Expand All @@ -149,6 +167,7 @@ struct swapchain_data {
std::mutex global_lock;
typedef std::lock_guard<std::mutex> scoped_lock;
std::unordered_map<uint64_t, void *> vk_object_to_data;
static struct swapchain_data* _swapchain_ref = NULL;

thread_local ImGuiContext* __MesaImGui;

Expand Down Expand Up @@ -363,6 +382,7 @@ static struct swapchain_data *new_swapchain_data(VkSwapchainKHR swapchain,
data->swapchain = swapchain;
data->window_size = ImVec2(instance_data->params.width, instance_data->params.height);
map_object(HKEY(data->swapchain), data);
_swapchain_ref = data;
return data;
}

Expand Down Expand Up @@ -471,12 +491,12 @@ static uint32_t vk_memory_type(struct device_data *data,
return 0xFFFFFFFF; // Unable to find memoryType
}

static void update_image_descriptor(struct swapchain_data *data, VkImageView image_view, VkDescriptorSet set)
static void update_image_descriptor(struct swapchain_data *data, VkImageView image_view, VkDescriptorSet set, VkSampler sampler)
{
struct device_data *device_data = data->device;
/* Descriptor set */
VkDescriptorImageInfo desc_image[1] = {};
desc_image[0].sampler = data->font_sampler;
desc_image[0].sampler = sampler;
desc_image[0].imageView = image_view;
desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkWriteDescriptorSet write_desc[1] = {};
Expand Down Expand Up @@ -596,7 +616,8 @@ static void create_image(struct swapchain_data *data,
VkFormat format,
VkImage& image,
VkDeviceMemory& image_mem,
VkImageView& image_view)
VkImageView& image_view,
VkSampler sampler)
{
struct device_data *device_data = data->device;

Expand Down Expand Up @@ -643,7 +664,7 @@ static void create_image(struct swapchain_data *data,
VK_CHECK(device_data->vtable.CreateImageView(device_data->device, &view_info,
NULL, &image_view));

update_image_descriptor(data, image_view, descriptor_set);
update_image_descriptor(data, image_view, descriptor_set, sampler);
}

static VkDescriptorSet create_image_with_desc(struct swapchain_data *data,
Expand All @@ -652,7 +673,8 @@ static VkDescriptorSet create_image_with_desc(struct swapchain_data *data,
VkFormat format,
VkImage& image,
VkDeviceMemory& image_mem,
VkImageView& image_view)
VkImageView& image_view,
VkSampler sampler)
{
struct device_data *device_data = data->device;

Expand All @@ -667,7 +689,7 @@ static VkDescriptorSet create_image_with_desc(struct swapchain_data *data,
&alloc_info,
&descriptor_set));

create_image(data, descriptor_set, width, height, format, image, image_mem, image_view);
create_image(data, descriptor_set, width, height, format, image, image_mem, image_view, sampler);
return descriptor_set;
}

Expand All @@ -692,9 +714,9 @@ static void check_fonts(struct swapchain_data* data)
shutdown_swapchain_font(data);

if (desc_set)
create_image(data, desc_set, width, height, VK_FORMAT_R8G8B8A8_SRGB, data->font_image, data->font_mem, data->font_image_view);
create_image(data, desc_set, width, height, VK_FORMAT_R8G8B8A8_SRGB, data->font_image, data->font_mem, data->font_image_view, data->font_sampler);
else
desc_set = create_image_with_desc(data, width, height, VK_FORMAT_R8G8B8A8_SRGB, data->font_image, data->font_mem, data->font_image_view);
desc_set = create_image_with_desc(data, width, height, VK_FORMAT_R8G8B8A8_SRGB, data->font_image, data->font_mem, data->font_image_view, data->font_sampler);

io.Fonts->SetTexID((ImTextureID)desc_set);
data->font_uploaded = false;
Expand Down Expand Up @@ -722,6 +744,34 @@ static void ensure_swapchain_fonts(struct swapchain_data *data,
upload_image_data(device_data, command_buffer, pixels, upload_size, width, height, data->upload_font_buffer, data->upload_font_buffer_mem, data->font_image);
}

ImTextureID addTexture(const std::string& filename, int* width, int* height, int maxwidth) {
struct swapchain_data *data = _swapchain_ref;
struct texture_info ti;
int original_width, original_height, channels;

// load
unsigned char* pixels = stbi_load(filename.c_str(), &original_width, &original_height, &channels, STBI_rgb_alpha);
stbi_image_free(pixels);

// reduce the image
float ratio = 1.0;
if(original_width > maxwidth && maxwidth != 0) {
ratio = maxwidth / ((float) original_width);
}
*width = (float)(original_width * ratio);
*height = (float)(original_height * ratio);
//

ti.descset = create_image_with_desc(data, *width, *height, VK_FORMAT_R8G8B8A8_SRGB, ti.image, ti.mem, ti.image_view, data->texture_sampler);
ti.filename = filename;
ti.maxwidth = maxwidth;
ti.uploaded = false;

data->textures.push_back(ti);

return (ImTextureID) ti.descset;
}

static void CreateOrResizeBuffer(struct device_data *data,
VkBuffer *buffer,
VkDeviceMemory *buffer_memory,
Expand Down Expand Up @@ -789,6 +839,35 @@ static struct overlay_draw *render_swapchain_display(struct swapchain_data *data

ensure_swapchain_fonts(data, draw->command_buffer);

/* ensure_textures */
int original_width, original_height, channels;
for(unsigned int i=0; i<data->textures.size(); i++) {
if(data->textures[i].uploaded == false) {
data->textures[i].uploaded = true;

// load
unsigned char* pixels = stbi_load(data->textures[i].filename.c_str(), &original_width, &original_height, &channels, STBI_rgb_alpha);

// reduce the image
float ratio = 1.0;
if(original_width > data->textures[i].maxwidth && data->textures[i].maxwidth != 0) {
ratio = data->textures[i].maxwidth / ((float) original_width);
}
int width = (float)(original_width * ratio);
int height = (float)(original_height * ratio);
unsigned char* pixels_resized = (unsigned char*)malloc(width * height * 4);
stbir_resize_uint8(pixels, original_width, original_height, 0,
pixels_resized, width, height, 0,
4);
stbi_image_free(pixels);
//

size_t upload_size = width * height * 4 * sizeof(char);
upload_image_data(device_data, draw->command_buffer, pixels_resized, upload_size, width, height, data->textures[i].upload_buffer, data->textures[i].upload_buffer_mem, data->textures[i].image);
stbi_image_free(pixels_resized);
}
}

/* Bounce the image to display back to color attachment layout for
* rendering on top of it.
*/
Expand Down Expand Up @@ -865,7 +944,7 @@ static struct overlay_draw *render_swapchain_display(struct swapchain_data *data
/* Bind pipeline and descriptor sets */
device_data->vtable.CmdBindPipeline(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, data->pipeline);

#if 1 // disable if using >1 font textures
#if 0 // disable if using >1 font textures
VkDescriptorSet desc_set[1] = {
//data->descriptor_set
reinterpret_cast<VkDescriptorSet>(ImGui::GetIO().Fonts->Fonts[0]->ContainerAtlas->TexID)
Expand Down Expand Up @@ -928,7 +1007,7 @@ static struct overlay_draw *render_swapchain_display(struct swapchain_data *data
scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here?
device_data->vtable.CmdSetScissor(draw->command_buffer, 0, 1, &scissor);
#if 0 //enable if using >1 font textures or use texture array
#if 1 //enable if using >1 font textures or use texture array
VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->TextureId };
device_data->vtable.CmdBindDescriptorSets(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
data->pipeline_layout, 0, 1, desc_set, 0, NULL);
Expand Down Expand Up @@ -1061,21 +1140,37 @@ static void setup_swapchain_data_pipeline(struct swapchain_data *data)
VK_CHECK(device_data->vtable.CreateSampler(device_data->device, &sampler_info,
NULL, &data->font_sampler));

/* Texture sampler */
VkSamplerCreateInfo texture_sampler_info = {};
texture_sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
texture_sampler_info.magFilter = VK_FILTER_LINEAR;
texture_sampler_info.minFilter = VK_FILTER_LINEAR;
texture_sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
texture_sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
texture_sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
texture_sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
texture_sampler_info.minLod = -1000;
texture_sampler_info.maxLod = 1000;
texture_sampler_info.maxAnisotropy = 1.0f;

VK_CHECK(device_data->vtable.CreateSampler(device_data->device, &texture_sampler_info,
NULL, &data->texture_sampler));

/* Descriptor pool */
VkDescriptorPoolSize sampler_pool_size = {};
sampler_pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
sampler_pool_size.descriptorCount = 1;
VkDescriptorPoolCreateInfo desc_pool_info = {};
desc_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
desc_pool_info.maxSets = 1;
desc_pool_info.poolSizeCount = 1;
desc_pool_info.maxSets = 3; // fonts + image + background_image
desc_pool_info.poolSizeCount = 3; // fonts + image + background_image
desc_pool_info.pPoolSizes = &sampler_pool_size;
VK_CHECK(device_data->vtable.CreateDescriptorPool(device_data->device,
&desc_pool_info,
NULL, &data->descriptor_pool));

/* Descriptor layout */
VkSampler sampler[1] = { data->font_sampler };
VkSampler sampler[2] = { data->font_sampler, data->texture_sampler};
VkDescriptorSetLayoutBinding binding[1] = {};
binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
binding[0].descriptorCount = 1;
Expand Down Expand Up @@ -1402,6 +1497,14 @@ static void shutdown_swapchain_font(struct swapchain_data *data)

device_data->vtable.DestroyBuffer(device_data->device, data->upload_font_buffer, NULL);
device_data->vtable.FreeMemory(device_data->device, data->upload_font_buffer_mem, NULL);

for(unsigned int i=0; i<data->textures.size(); i++) {
device_data->vtable.DestroyImageView(device_data->device, data->textures[i].image_view, NULL);
device_data->vtable.DestroyImage(device_data->device, data->textures[i].image, NULL);
device_data->vtable.FreeMemory(device_data->device, data->textures[i].mem, NULL);
device_data->vtable.DestroyBuffer(device_data->device, data->textures[i].upload_buffer, NULL);
device_data->vtable.FreeMemory(device_data->device, data->textures[i].upload_buffer_mem, NULL);
}
}

static void shutdown_swapchain_data(struct swapchain_data *data)
Expand Down Expand Up @@ -1437,6 +1540,7 @@ static void shutdown_swapchain_data(struct swapchain_data *data)
data->descriptor_layout, NULL);

device_data->vtable.DestroySampler(device_data->device, data->font_sampler, NULL);
device_data->vtable.DestroySampler(device_data->device, data->texture_sampler, NULL);
shutdown_swapchain_font(data);

ImGui::DestroyContext(data->imgui_context);
Expand Down

0 comments on commit 0e1a377

Please sign in to comment.