vk: Implement 2D array textures required for new font subsystem

This commit is contained in:
kd-11
2020-02-19 18:50:32 +03:00
committed by kd-11
parent 1df1ceb4ea
commit 6220206cbc
6 changed files with 160 additions and 57 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ namespace vk
for (auto &e : image_list) for (auto &e : image_list)
{ {
const VkImageSubresourceRange subres = { e->aspect(), 0, 1, 0, 1 }; const VkImageSubresourceRange subres = { e->aspect(), 0, 1, 0, 1 };
image_views.push_back(std::make_unique<vk::image_view>(dev, e, vk::default_component_map(), subres)); image_views.push_back(std::make_unique<vk::image_view>(dev, e, VK_IMAGE_VIEW_TYPE_2D, vk::default_component_map(), subres));
} }
auto value = std::make_unique<vk::framebuffer_holder>(dev, renderpass, width, height, std::move(image_views)); auto value = std::make_unique<vk::framebuffer_holder>(dev, renderpass, width, height, std::move(image_views));
+24 -4
View File
@@ -230,6 +230,22 @@ namespace vk
fmt::throw_exception("Unknown cull face value: 0x%x" HERE, static_cast<u32>(cfv)); fmt::throw_exception("Unknown cull face value: 0x%x" HERE, static_cast<u32>(cfv));
} }
} }
VkImageViewType get_view_type(rsx::texture_dimension_extended type)
{
switch (type)
{
case rsx::texture_dimension_extended::texture_dimension_1d:
return VK_IMAGE_VIEW_TYPE_1D;
case rsx::texture_dimension_extended::texture_dimension_2d:
return VK_IMAGE_VIEW_TYPE_2D;
case rsx::texture_dimension_extended::texture_dimension_cubemap:
return VK_IMAGE_VIEW_TYPE_CUBE;
case rsx::texture_dimension_extended::texture_dimension_3d:
return VK_IMAGE_VIEW_TYPE_3D;
default: ASSUME(0);
};
}
} }
namespace namespace
@@ -1669,14 +1685,15 @@ void VKGSRender::end()
} }
else else
{ {
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, const VkImageViewType view_type = vk::get_view_type(current_fragment_program.get_texture_dimension(i));
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i, i,
::glsl::program_domain::glsl_fragment_program, ::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set); m_current_frame->descriptor_set);
if (current_fragment_program.redirected_textures & (1 << i)) if (current_fragment_program.redirected_textures & (1 << i))
{ {
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i, i,
::glsl::program_domain::glsl_fragment_program, ::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set, m_current_frame->descriptor_set,
@@ -1692,7 +1709,8 @@ void VKGSRender::end()
{ {
if (!rsx::method_registers.vertex_textures[i].enabled()) if (!rsx::method_registers.vertex_textures[i].enabled())
{ {
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, const auto view_type = vk::get_view_type(current_vertex_program.get_texture_dimension(i));
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i, i,
::glsl::program_domain::glsl_vertex_program, ::glsl::program_domain::glsl_vertex_program,
m_current_frame->descriptor_set); m_current_frame->descriptor_set);
@@ -1712,7 +1730,9 @@ void VKGSRender::end()
if (!image_ptr) if (!image_ptr)
{ {
rsx_log.error("Texture upload failed to vtexture index %d. Binding null sampler.", i); rsx_log.error("Texture upload failed to vtexture index %d. Binding null sampler.", i);
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, const auto view_type = vk::get_view_type(current_vertex_program.get_texture_dimension(i));
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i, i,
::glsl::program_domain::glsl_vertex_program, ::glsl::program_domain::glsl_vertex_program,
m_current_frame->descriptor_set); m_current_frame->descriptor_set);
+23 -17
View File
@@ -67,8 +67,8 @@ namespace vk
const render_device* g_current_renderer; const render_device* g_current_renderer;
std::unique_ptr<image> g_null_texture; std::unique_ptr<image> g_null_texture;
std::unique_ptr<image_view> g_null_image_view;
std::unique_ptr<buffer> g_scratch_buffer; std::unique_ptr<buffer> g_scratch_buffer;
std::unordered_map<VkImageViewType, std::unique_ptr<image_view>> g_null_image_views;
std::unordered_map<u32, std::unique_ptr<image>> g_typeless_textures; std::unordered_map<u32, std::unique_ptr<image>> g_typeless_textures;
std::unordered_map<u32, std::unique_ptr<vk::compute_task>> g_compute_tasks; std::unordered_map<u32, std::unique_ptr<vk::compute_task>> g_compute_tasks;
@@ -289,26 +289,32 @@ namespace vk
return g_null_sampler; return g_null_sampler;
} }
vk::image_view* null_image_view(vk::command_buffer &cmd) vk::image_view* null_image_view(vk::command_buffer &cmd, VkImageViewType type)
{ {
if (g_null_image_view) if (auto found = g_null_image_views.find(type);
return g_null_image_view.get(); found != g_null_image_views.end())
{
return found->second.get();
}
g_null_texture = std::make_unique<image>(*g_current_renderer, g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, if (!g_null_texture)
VK_IMAGE_TYPE_2D, VK_FORMAT_B8G8R8A8_UNORM, 4, 4, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, {
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0); g_null_texture = std::make_unique<image>(*g_current_renderer, g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D, VK_FORMAT_B8G8R8A8_UNORM, 4, 4, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0);
g_null_image_view = std::make_unique<image_view>(*g_current_renderer, g_null_texture.get()); // Initialize memory to transparent black
VkClearColorValue clear_color = {};
VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
change_image_layout(cmd, g_null_texture.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
vkCmdClearColorImage(cmd, g_null_texture->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range);
// Initialize memory to transparent black // Prep for shader access
VkClearColorValue clear_color = {}; change_image_layout(cmd, g_null_texture.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; }
change_image_layout(cmd, g_null_texture.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
vkCmdClearColorImage(cmd, g_null_texture->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range);
// Prep for shader access auto& ret = g_null_image_views[type] = std::make_unique<image_view>(*g_current_renderer, g_null_texture.get(), type);
change_image_layout(cmd, g_null_texture.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range); return ret.get();
return g_null_image_view.get();
} }
vk::image* get_typeless_helper(VkFormat format, u32 requested_width, u32 requested_height) vk::image* get_typeless_helper(VkFormat format, u32 requested_width, u32 requested_height)
@@ -396,7 +402,7 @@ namespace vk
vk::get_resource_manager()->destroy(); vk::get_resource_manager()->destroy();
g_null_texture.reset(); g_null_texture.reset();
g_null_image_view.reset(); g_null_image_views.clear();
g_scratch_buffer.reset(); g_scratch_buffer.reset();
g_upload_heap.destroy(); g_upload_heap.destroy();
+37 -20
View File
@@ -141,7 +141,7 @@ namespace vk
VkImageAspectFlags get_aspect_flags(VkFormat format); VkImageAspectFlags get_aspect_flags(VkFormat format);
VkSampler null_sampler(); VkSampler null_sampler();
image_view* null_image_view(vk::command_buffer&); image_view* null_image_view(vk::command_buffer&, VkImageViewType type);
image* get_typeless_helper(VkFormat format, u32 requested_width, u32 requested_height); image* get_typeless_helper(VkFormat format, u32 requested_width, u32 requested_height);
buffer* get_scratch_buffer(u32 min_required_size = 0); buffer* get_scratch_buffer(u32 min_required_size = 0);
data_heap* get_upload_heap(); data_heap* get_upload_heap();
@@ -1387,6 +1387,11 @@ private:
return info.mipLevels; return info.mipLevels;
} }
u32 layers() const
{
return info.arrayLayers;
}
u8 samples() const u8 samples() const
{ {
return u8(info.samples); return u8(info.samples);
@@ -1456,8 +1461,9 @@ private:
} }
image_view(VkDevice dev, vk::image* resource, image_view(VkDevice dev, vk::image* resource,
const VkComponentMapping mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }, VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_MAX_ENUM,
const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}) const VkComponentMapping& mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
const VkImageSubresourceRange& range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1})
: m_device(dev), m_resource(resource) : m_device(dev), m_resource(resource)
{ {
info.format = resource->info.format; info.format = resource->info.format;
@@ -1466,23 +1472,34 @@ private:
info.components = mapping; info.components = mapping;
info.subresourceRange = range; info.subresourceRange = range;
switch (resource->info.imageType) if (view_type == VK_IMAGE_VIEW_TYPE_MAX_ENUM)
{ {
case VK_IMAGE_TYPE_1D: switch (resource->info.imageType)
info.viewType = VK_IMAGE_VIEW_TYPE_1D; {
break; case VK_IMAGE_TYPE_1D:
case VK_IMAGE_TYPE_2D: info.viewType = VK_IMAGE_VIEW_TYPE_1D;
if (resource->info.flags == VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) break;
info.viewType = VK_IMAGE_VIEW_TYPE_CUBE; case VK_IMAGE_TYPE_2D:
else if (resource->info.flags == VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
info.viewType = VK_IMAGE_VIEW_TYPE_2D; info.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
break; else if (resource->info.arrayLayers == 1)
case VK_IMAGE_TYPE_3D: info.viewType = VK_IMAGE_VIEW_TYPE_2D;
info.viewType = VK_IMAGE_VIEW_TYPE_3D; else
break; info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
default: break;
ASSUME(0); case VK_IMAGE_TYPE_3D:
break; info.viewType = VK_IMAGE_VIEW_TYPE_3D;
break;
default:
ASSUME(0);
break;
}
info.subresourceRange.layerCount = resource->info.arrayLayers;
}
else
{
info.viewType = view_type;
} }
create_impl(); create_impl();
@@ -1588,7 +1605,7 @@ private:
const auto range = vk::get_image_subresource_range(0, 0, info.arrayLayers, info.mipLevels, aspect() & mask); const auto range = vk::get_image_subresource_range(0, 0, info.arrayLayers, info.mipLevels, aspect() & mask);
verify(HERE), range.aspectMask; verify(HERE), range.aspectMask;
auto view = std::make_unique<vk::image_view>(*get_current_renderer(), this, real_mapping, range); auto view = std::make_unique<vk::image_view>(*get_current_renderer(), this, VK_IMAGE_VIEW_TYPE_MAX_ENUM, real_mapping, range);
auto result = view.get(); auto result = view.get();
views.emplace(remap_encoding, std::move(view)); views.emplace(remap_encoding, std::move(view));
+61 -15
View File
@@ -4,6 +4,7 @@
#include "VKFragmentProgram.h" #include "VKFragmentProgram.h"
#include "VKRenderTargets.h" #include "VKRenderTargets.h"
#include "VKFramebuffer.h" #include "VKFramebuffer.h"
#include "VKResourceManager.h"
#include "../Overlays/overlays.h" #include "../Overlays/overlays.h"
@@ -529,6 +530,7 @@ namespace vk
"#version 420\n" "#version 420\n"
"#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_separate_shader_objects : enable\n"
"layout(set=0, binding=1) uniform sampler2D fs0;\n" "layout(set=0, binding=1) uniform sampler2D fs0;\n"
"layout(set=0, binding=2) uniform sampler2DArray fs1;\n"
"layout(location=0) in vec2 tc0;\n" "layout(location=0) in vec2 tc0;\n"
"layout(location=1) in vec4 color;\n" "layout(location=1) in vec4 color;\n"
"layout(location=2) in vec4 parameters;\n" "layout(location=2) in vec4 parameters;\n"
@@ -602,16 +604,29 @@ namespace vk
" diff_color.a *= (sin(parameters.x) + 1.f) * 0.5f;\n" " diff_color.a *= (sin(parameters.x) + 1.f) * 0.5f;\n"
"\n" "\n"
" if (parameters.z < 1.)\n" " if (parameters.z < 1.)\n"
" {\n"
" ocol = diff_color;\n" " ocol = diff_color;\n"
" }\n"
" else if (parameters.z > 2.)\n"
" {\n"
" ocol = texture(fs1, vec3(tc0.x, fract(tc0.y), trunc(tc0.y))).rrrr * diff_color;\n"
" }\n"
" else if (parameters.z > 1.)\n" " else if (parameters.z > 1.)\n"
" {\n"
" ocol = texture(fs0, tc0).rrrr * diff_color;\n" " ocol = texture(fs0, tc0).rrrr * diff_color;\n"
" }\n"
" else\n" " else\n"
" {\n"
" ocol = sample_image(fs0, tc0, parameters2.x).bgra * diff_color;\n" " ocol = sample_image(fs0, tc0, parameters2.x).bgra * diff_color;\n"
" }\n"
"}\n"; "}\n";
// Allow mixed primitive rendering // Allow mixed primitive rendering
multi_primitive = true; multi_primitive = true;
// 2 input textures
m_num_usable_samplers = 2;
renderpass_config.set_attachment_count(1); renderpass_config.set_attachment_count(1);
renderpass_config.set_color_mask(0, true, true, true, true); renderpass_config.set_color_mask(0, true, true, true, true);
renderpass_config.set_depth_mask(false); renderpass_config.set_depth_mask(false);
@@ -622,18 +637,18 @@ namespace vk
} }
vk::image_view* upload_simple_texture(vk::render_device &dev, vk::command_buffer &cmd, vk::image_view* upload_simple_texture(vk::render_device &dev, vk::command_buffer &cmd,
vk::data_heap& upload_heap, u64 key, int w, int h, bool font, bool temp, void *pixel_src, u32 owner_uid) vk::data_heap& upload_heap, u64 key, u32 w, u32 h, u32 layers, bool font, bool temp, void *pixel_src, u32 owner_uid)
{ {
const VkFormat format = (font) ? VK_FORMAT_R8_UNORM : VK_FORMAT_B8G8R8A8_UNORM; const VkFormat format = (font) ? VK_FORMAT_R8_UNORM : VK_FORMAT_B8G8R8A8_UNORM;
const u32 pitch = (font) ? w : w * 4; const u32 pitch = (font) ? w : w * 4;
const u32 data_size = pitch * h; const u32 data_size = pitch * h * layers;
const auto offset = upload_heap.alloc<512>(data_size); const auto offset = upload_heap.alloc<512>(data_size);
const auto addr = upload_heap.map(offset, data_size); const auto addr = upload_heap.map(offset, data_size);
const VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; const VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, layers };
auto tex = std::make_unique<vk::image>(dev, dev.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, auto tex = std::make_unique<vk::image>(dev, dev.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D, format, std::max(w, 1), std::max(h, 1), 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TYPE_2D, format, std::max(w, 1u), std::max(h, 1u), 1, 1, layers, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
0); 0);
@@ -645,12 +660,12 @@ namespace vk
upload_heap.unmap(); upload_heap.unmap();
VkBufferImageCopy region; VkBufferImageCopy region;
region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, layers };
region.bufferOffset = offset; region.bufferOffset = offset;
region.bufferRowLength = w; region.bufferRowLength = w;
region.bufferImageHeight = h; region.bufferImageHeight = h;
region.imageOffset = {}; region.imageOffset = {};
region.imageExtent = { static_cast<u32>(w), static_cast<u32>(h), 1u}; region.imageExtent = { static_cast<u32>(w), static_cast<u32>(h), 1u };
change_image_layout(cmd, tex.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range); change_image_layout(cmd, tex.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
vkCmdCopyBufferToImage(cmd, upload_heap.heap->value, tex->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); vkCmdCopyBufferToImage(cmd, upload_heap.heap->value, tex->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
@@ -686,7 +701,7 @@ namespace vk
u64 storage_key = 1; u64 storage_key = 1;
for (const auto &res : configuration.texture_raw_data) for (const auto &res : configuration.texture_raw_data)
{ {
upload_simple_texture(dev, cmd, upload_heap, storage_key++, res->w, res->h, false, false, res->data, UINT32_MAX); upload_simple_texture(dev, cmd, upload_heap, storage_key++, res->w, res->h, 1, false, false, res->data, UINT32_MAX);
} }
configuration.free_resources(); configuration.free_resources();
@@ -724,14 +739,33 @@ namespace vk
vk::image_view* find_font(rsx::overlays::font *font, vk::command_buffer &cmd, vk::data_heap &upload_heap) vk::image_view* find_font(rsx::overlays::font *font, vk::command_buffer &cmd, vk::data_heap &upload_heap)
{ {
const auto image_size = font->get_glyph_data_dimensions();
u64 key = reinterpret_cast<u64>(font); u64 key = reinterpret_cast<u64>(font);
auto found = view_cache.find(key); auto found = view_cache.find(key);
if (found != view_cache.end()) if (found != view_cache.end())
return found->second.get(); {
if (const auto raw = found->second->image();
image_size.width == raw->width() &&
image_size.height == raw->height() &&
image_size.depth == raw->layers())
{
return found->second.get();
}
else
{
auto gc = vk::get_resource_manager();
gc->dispose(font_cache[key]);
gc->dispose(view_cache[key]);
}
}
//Create font file // Create font resource
return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, font->width, font->height, std::vector<u8> bytes;
true, false, font->glyph_data.data(), UINT32_MAX); font->get_glyph_data(bytes);
return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, image_size.width, image_size.height, image_size.depth,
true, false, bytes.data(), UINT32_MAX);
} }
vk::image_view* find_temp_image(rsx::overlays::image_info *desc, vk::command_buffer &cmd, vk::data_heap &upload_heap, u32 owner_uid) vk::image_view* find_temp_image(rsx::overlays::image_info *desc, vk::command_buffer &cmd, vk::data_heap &upload_heap, u32 owner_uid)
@@ -741,7 +775,7 @@ namespace vk
if (found != temp_view_cache.end()) if (found != temp_view_cache.end())
return found->second.get(); return found->second.get();
return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, desc->w, desc->h, return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, desc->w, desc->h, 1,
false, true, desc->data, owner_uid); false, true, desc->data, owner_uid);
} }
@@ -834,6 +868,12 @@ namespace vk
m_time = static_cast<f32>(get_system_time() / 1000) * 0.005f; m_time = static_cast<f32>(get_system_time() / 1000) * 0.005f;
m_viewport = { { static_cast<f32>(viewport.x1), static_cast<f32>(viewport.y1) }, { static_cast<f32>(viewport.width()), static_cast<f32>(viewport.height()) } }; m_viewport = { { static_cast<f32>(viewport.x1), static_cast<f32>(viewport.y1) }, { static_cast<f32>(viewport.width()), static_cast<f32>(viewport.height()) } };
std::vector<vk::image_view*> image_views
{
vk::null_image_view(cmd, VK_IMAGE_VIEW_TYPE_2D),
vk::null_image_view(cmd, VK_IMAGE_VIEW_TYPE_2D_ARRAY)
};
for (auto &command : ui.get_compiled().draw_commands) for (auto &command : ui.get_compiled().draw_commands)
{ {
num_drawable_elements = static_cast<u32>(command.verts.size()); num_drawable_elements = static_cast<u32>(command.verts.size());
@@ -850,7 +890,7 @@ namespace vk
m_clip_region = command.config.clip_rect; m_clip_region = command.config.clip_rect;
m_texture_type = 1; m_texture_type = 1;
auto src = vk::null_image_view(cmd); vk::image_view* src = nullptr;
switch (command.config.texture_ref) switch (command.config.texture_ref)
{ {
case rsx::overlays::image_resource_id::game_icon: case rsx::overlays::image_resource_id::game_icon:
@@ -860,8 +900,8 @@ namespace vk
m_skip_texture_read = true; m_skip_texture_read = true;
break; break;
case rsx::overlays::image_resource_id::font_file: case rsx::overlays::image_resource_id::font_file:
m_texture_type = 2;
src = find_font(command.config.font_ref, cmd, upload_heap); src = find_font(command.config.font_ref, cmd, upload_heap);
m_texture_type = src->image()->layers() == 1 ? 2 : 3;
break; break;
case rsx::overlays::image_resource_id::raw_image: case rsx::overlays::image_resource_id::raw_image:
src = find_temp_image(static_cast<rsx::overlays::image_info*>(command.config.external_data_ref), cmd, upload_heap, ui.uid); src = find_temp_image(static_cast<rsx::overlays::image_info*>(command.config.external_data_ref), cmd, upload_heap, ui.uid);
@@ -871,7 +911,13 @@ namespace vk
break; break;
} }
overlay_pass::run(cmd, viewport, target, { src }, render_pass); if (src)
{
const int res_id = src->image()->layers() > 1 ? 1 : 0;
image_views[res_id] = src;
}
overlay_pass::run(cmd, viewport, target, image_views, render_pass);
} }
ui.update(); ui.update();
+14
View File
@@ -12,6 +12,8 @@ namespace vk
u64 eid; u64 eid;
const vk::render_device* m_device; const vk::render_device* m_device;
std::vector<std::unique_ptr<vk::buffer>> m_disposed_buffers; std::vector<std::unique_ptr<vk::buffer>> m_disposed_buffers;
std::vector<std::unique_ptr<vk::image_view>> m_disposed_image_views;
std::vector<std::unique_ptr<vk::image>> m_disposed_images;
rsx::simple_array<VkEvent> m_disposed_events; rsx::simple_array<VkEvent> m_disposed_events;
eid_scope_t(u64 _eid): eid_scope_t(u64 _eid):
@@ -36,6 +38,8 @@ namespace vk
} }
m_disposed_buffers.clear(); m_disposed_buffers.clear();
m_disposed_image_views.clear();
m_disposed_images.clear();
} }
}; };
@@ -132,6 +136,16 @@ namespace vk
get_current_eid_scope().m_disposed_buffers.emplace_back(std::move(buf)); get_current_eid_scope().m_disposed_buffers.emplace_back(std::move(buf));
} }
void dispose(std::unique_ptr<vk::image_view>& view)
{
get_current_eid_scope().m_disposed_image_views.emplace_back(std::move(view));
}
void dispose(std::unique_ptr<vk::image>& img)
{
get_current_eid_scope().m_disposed_images.emplace_back(std::move(img));
}
void dispose(VkEvent& event) void dispose(VkEvent& event)
{ {
get_current_eid_scope().m_disposed_events.push_back(event); get_current_eid_scope().m_disposed_events.push_back(event);