vk: Enable use of input attachments

This commit is contained in:
kd-11 2021-05-31 22:59:39 +03:00 committed by kd-11
parent b8b5b93b63
commit f85881c18c
9 changed files with 273 additions and 117 deletions

View File

@ -10,10 +10,26 @@ namespace vk
{
std::unordered_map<u64, std::vector<std::unique_ptr<vk::framebuffer_holder>>> g_framebuffers_cache;
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkRenderPass renderpass, const std::vector<vk::image*>& image_list)
union framebuffer_storage_key
{
u64 key = u64(width) | (u64(height) << 16);
auto &queue = g_framebuffers_cache[key];
u64 encoded;
struct
{
u64 width : 16; // Width of FBO
u64 height : 16; // Height of FBO
u64 ia_ref : 1; // Input attachment references?
};
framebuffer_storage_key(u16 width_, u16 height_, VkBool32 has_input_attachments)
: width(width_), height(height_), ia_ref(has_input_attachments)
{}
};
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkBool32 has_input_attachments, VkRenderPass renderpass, const std::vector<vk::image*>& image_list)
{
framebuffer_storage_key key(width, height, has_input_attachments);
auto &queue = g_framebuffers_cache[key.encoded];
for (auto &fbo : queue)
{
@ -39,10 +55,10 @@ namespace vk
return ret;
}
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkRenderPass renderpass, VkFormat format, VkImage attachment)
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkBool32 has_input_attachments, VkRenderPass renderpass, VkFormat format, VkImage attachment)
{
u64 key = u64(width) | (u64(height) << 16);
auto &queue = g_framebuffers_cache[key];
framebuffer_storage_key key(width, height, has_input_attachments);
auto &queue = g_framebuffers_cache[key.encoded];
for (const auto &e : queue)
{

View File

@ -9,8 +9,8 @@ namespace vk
using framebuffer::framebuffer;
};
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkRenderPass renderpass, const std::vector<vk::image*>& image_list);
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkRenderPass renderpass, VkFormat format, VkImage attachment);
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkBool32 has_input_attachments, VkRenderPass renderpass, const std::vector<vk::image*>& image_list);
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkBool32 has_input_attachments, VkRenderPass renderpass, VkFormat format, VkImage attachment);
void remove_unused_framebuffers();
void clear_framebuffer_cache();

View File

@ -1289,7 +1289,8 @@ void VKGSRender::clear_surface(u32 mask)
if (!renderpass)
{
std::vector<vk::image*> surfaces = { rtt };
const auto key = vk::get_renderpass_key(surfaces);
std::vector<u8> input_attachments = { 0 };
const auto key = vk::get_renderpass_key(surfaces, input_attachments);
renderpass = vk::get_renderpass(*m_device, key);
}
@ -2277,7 +2278,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
m_draw_fbo->release();
}
m_draw_fbo = vk::get_framebuffer(*m_device, fbo_width, fbo_height, m_cached_renderpass, m_fbo_images);
m_draw_fbo = vk::get_framebuffer(*m_device, fbo_width, fbo_height, VK_FALSE, m_cached_renderpass, m_fbo_images);
m_draw_fbo->add_ref();
set_viewport();

View File

@ -60,16 +60,26 @@ namespace vk
void overlay_pass::init_descriptors()
{
VkDescriptorPoolSize descriptor_pool_sizes[2] =
std::vector<VkDescriptorPoolSize> descriptor_pool_sizes =
{
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_OVERLAY_MAX_DRAW_CALLS * m_num_usable_samplers },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_OVERLAY_MAX_DRAW_CALLS },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_OVERLAY_MAX_DRAW_CALLS }
};
// Reserve descriptor pools
m_descriptor_pool.create(*m_device, descriptor_pool_sizes, 2, VK_OVERLAY_MAX_DRAW_CALLS, 2);
if (m_num_usable_samplers)
{
descriptor_pool_sizes.push_back({ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_OVERLAY_MAX_DRAW_CALLS * m_num_usable_samplers });
}
std::vector<VkDescriptorSetLayoutBinding> bindings(1 + m_num_usable_samplers);
if (m_num_input_attachments)
{
descriptor_pool_sizes.push_back({ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_OVERLAY_MAX_DRAW_CALLS * m_num_input_attachments });
}
// Reserve descriptor pools
m_descriptor_pool.create(*m_device, descriptor_pool_sizes.data(), ::size32(descriptor_pool_sizes), VK_OVERLAY_MAX_DRAW_CALLS, 2);
const auto num_bindings = 1 + m_num_usable_samplers + m_num_input_attachments;
std::vector<VkDescriptorSetLayoutBinding> bindings(num_bindings);
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
bindings[0].descriptorCount = 1;
@ -77,19 +87,31 @@ namespace vk
bindings[0].binding = 0;
bindings[0].pImmutableSamplers = nullptr;
for (u32 n = 1; n <= m_num_usable_samplers; ++n)
u32 descriptor_index = 1;
for (u32 n = 0; n < m_num_usable_samplers; ++n, ++descriptor_index)
{
bindings[n].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[n].descriptorCount = 1;
bindings[n].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[n].binding = n;
bindings[n].pImmutableSamplers = nullptr;
bindings[descriptor_index].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[descriptor_index].descriptorCount = 1;
bindings[descriptor_index].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[descriptor_index].binding = descriptor_index;
bindings[descriptor_index].pImmutableSamplers = nullptr;
}
for (u32 n = 0; n < m_num_input_attachments; ++n, ++descriptor_index)
{
bindings[descriptor_index].descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
bindings[descriptor_index].descriptorCount = 1;
bindings[descriptor_index].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[descriptor_index].binding = descriptor_index;
bindings[descriptor_index].pImmutableSamplers = nullptr;
}
ensure(descriptor_index == num_bindings);
VkDescriptorSetLayoutCreateInfo infos = {};
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
infos.pBindings = bindings.data();
infos.bindingCount = 1 + m_num_usable_samplers;
infos.bindingCount = ::size32(bindings);
CHECK_RESULT(vkCreateDescriptorSetLayout(*m_device, &infos, nullptr, &m_descriptor_layout));
@ -119,9 +141,15 @@ namespace vk
std::vector<vk::glsl::program_input> fs_inputs;
fs_inputs.push_back({ ::glsl::program_domain::glsl_fragment_program, vk::glsl::program_input_type::input_type_uniform_buffer,{},{}, 0, "static_data" });
for (u32 n = 1; n <= m_num_usable_samplers; ++n)
u32 binding = 1;
for (u32 n = 0; n < m_num_usable_samplers; ++n, ++binding)
{
fs_inputs.push_back({ ::glsl::program_domain::glsl_fragment_program, vk::glsl::program_input_type::input_type_texture,{},{}, n, "fs" + std::to_string(n-1) });
fs_inputs.push_back({ ::glsl::program_domain::glsl_fragment_program, vk::glsl::program_input_type::input_type_texture,{},{}, binding, "fs" + std::to_string(n) });
}
for (u32 n = 0; n < m_num_input_attachments; ++n, ++binding)
{
fs_inputs.push_back({ ::glsl::program_domain::glsl_fragment_program, vk::glsl::program_input_type::input_type_texture,{},{}, binding, "sp" + std::to_string(n) });
}
return fs_inputs;
@ -222,7 +250,7 @@ namespace vk
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &m_descriptor_set));
m_used_descriptors++;
if (!m_sampler)
if (!m_sampler && !src.empty())
{
m_sampler = std::make_unique<vk::sampler>(*m_device,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
@ -290,7 +318,7 @@ namespace vk
vk::framebuffer* overlay_pass::get_framebuffer(vk::image* target, VkRenderPass render_pass)
{
VkDevice dev = (*vk::get_current_renderer());
return vk::get_framebuffer(dev, target->width(), target->height(), render_pass, { target });
return vk::get_framebuffer(dev, target->width(), target->height(), m_num_input_attachments > 0, render_pass, { target });
}
void overlay_pass::emit_geometry(vk::command_buffer& cmd)
@ -778,15 +806,12 @@ namespace vk
"#version 450\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"layout(push_constant) uniform static_data{ vec4 regs[2]; };\n"
"layout(location=0) out vec2 tc0;\n"
"layout(location=1) out vec4 color;\n"
"layout(location=2) out vec4 mask;\n"
"layout(location=0) out vec4 color;\n"
"layout(location=1) out vec4 mask;\n"
"\n"
"void main()\n"
"{\n"
" vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n"
" vec2 coords[] = {vec2(0., 0.), vec2(1., 0.), vec2(0., 1.), vec2(1., 1.)};\n"
" tc0 = coords[gl_VertexIndex % 4];\n"
" color = regs[0];\n"
" mask = regs[1];\n"
" gl_Position = vec4(positions[gl_VertexIndex % 4], 0., 1.);\n"
@ -795,18 +820,23 @@ namespace vk
fs_src =
"#version 420\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"layout(set=0, binding=1) uniform sampler2D fs0;\n"
"layout(location=0) in vec2 tc0;\n"
"layout(location=1) in vec4 color;\n"
"layout(location=2) in vec4 mask;\n"
"layout(input_attachment_index=0, binding=1) uniform subpassInput sp0;\n"
"layout(location=0) in vec4 color;\n"
"layout(location=1) in vec4 mask;\n"
"layout(location=0) out vec4 out_color;\n"
"\n"
"void main()\n"
"{\n"
" vec4 original_color = texture(fs0, tc0);\n"
" vec4 original_color = subpassLoad(sp0);\n"
" out_color = mix(original_color, color, bvec4(mask));\n"
"}\n";
// Disable samplers
m_num_usable_samplers = 0;
// Enable subpass attachment 0
m_num_input_attachments = 1;
renderpass_config.set_depth_mask(false);
renderpass_config.set_color_mask(0, true, true, true, true);
renderpass_config.set_attachment_count(1);
@ -822,7 +852,7 @@ namespace vk
return { constant };
}
void attachment_clear_pass::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* /*program*/)
void attachment_clear_pass::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program)
{
f32 data[8];
data[0] = clear_color.r;
@ -835,6 +865,9 @@ namespace vk
data[7] = colormask.a;
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 32, data);
// Bind subpass attachment 0
program->bind_uniform(input_attachment_info, "sp0", VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_descriptor_set);
}
void attachment_clear_pass::set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h)
@ -872,13 +905,14 @@ namespace vk
void attachment_clear_pass::run(vk::command_buffer& cmd, vk::render_target* target, VkRect2D rect, VkRenderPass render_pass)
{
region = rect;
input_attachment_info = { VK_NULL_HANDLE, target->get_view(0xAAE4, rsx::default_remap_vector)->value, target->current_layout };
target->read_barrier(cmd);
// Coverage sampling disabled, but actually report correct number of samples
renderpass_config.set_multisample_state(target->samples(), 0xFFFF, false, false, false);
overlay_pass::run(cmd, { 0, 0, target->width(), target->height() }, target,
target->get_view(0xAAE4, rsx::default_remap_vector), render_pass);
overlay_pass::run(cmd, { 0, 0, target->width(), target->height() }, target, std::vector<vk::image_view*>{}, render_pass);
}
stencil_clear_pass::stencil_clear_pass()

View File

@ -49,6 +49,7 @@ namespace vk
VkFilter m_sampler_filter = VK_FILTER_LINEAR;
u32 m_num_usable_samplers = 1;
u32 m_num_input_attachments = 0;
std::unordered_map<u64, std::unique_ptr<vk::glsl::program>> m_program_cache;
std::unique_ptr<vk::sampler> m_sampler;
@ -175,12 +176,13 @@ namespace vk
color4f clear_color = { 0.f, 0.f, 0.f, 0.f };
color4f colormask = { 1.f, 1.f, 1.f, 1.f };
VkRect2D region = {};
VkDescriptorImageInfo input_attachment_info = {};
attachment_clear_pass();
std::vector<VkPushConstantRange> get_push_constants() override;
void update_uniforms(vk::command_buffer& cmd, vk::glsl::program* /*program*/) override;
void update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program) override;
void set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h) override;

View File

@ -637,7 +637,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
single_target_pass = vk::get_renderpass(*m_device, key);
ensure(single_target_pass != VK_NULL_HANDLE);
direct_fbo = vk::get_framebuffer(*m_device, m_swapchain_dims.width, m_swapchain_dims.height, single_target_pass, m_swapchain->get_surface_format(), target_image);
direct_fbo = vk::get_framebuffer(*m_device, m_swapchain_dims.width, m_swapchain_dims.height, VK_FALSE, single_target_pass, m_swapchain->get_surface_format(), target_image);
direct_fbo->add_ref();
image_to_flip->push_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
@ -715,7 +715,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
single_target_pass = vk::get_renderpass(*m_device, key);
ensure(single_target_pass != VK_NULL_HANDLE);
direct_fbo = vk::get_framebuffer(*m_device, m_swapchain_dims.width, m_swapchain_dims.height, single_target_pass, m_swapchain->get_surface_format(), target_image);
direct_fbo = vk::get_framebuffer(*m_device, m_swapchain_dims.width, m_swapchain_dims.height, VK_FALSE, single_target_pass, m_swapchain->get_surface_format(), target_image);
}
direct_fbo->add_ref();

View File

@ -19,77 +19,187 @@ namespace vk
shared_mutex g_renderpass_cache_mutex;
std::unordered_map<u64, VkRenderPass> g_renderpass_cache;
u64 get_renderpass_key(const std::vector<vk::image*>& images)
// Key structure
// 0-7 color_format
// 8-15 depth_format
// 16-21 sample_counts
// 22-36 current layouts
// 37-41 input attachments
union renderpass_key_blob
{
// Key structure
// 0-8 color_format
// 8-16 depth_format
// 16-21 sample_counts
// 21-37 current layouts
u64 key = 0;
u64 layout_offset = 22;
for (const auto &surface : images)
private:
// Internal utils
static u64 encode_layout(VkImageLayout layout)
{
const auto format_code = u64(surface->format()) & 0xFF;
switch (format_code)
switch (layout)
{
case VK_IMAGE_LAYOUT_GENERAL:
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
return static_cast<u64>(layout);
default:
fmt::throw_exception("Unsupported layout 0x%llx here", static_cast<usz>(layout));
}
}
static VkImageLayout decode_layout(u64 encoded)
{
switch (encoded)
{
case 1:
case 2:
case 3:
return static_cast<VkImageLayout>(encoded);
default:
fmt::throw_exception("Unsupported layout encoding 0x%llx here", encoded);
}
}
public:
u64 encoded;
struct
{
u64 color_format : 8;
u64 depth_format : 8;
u64 sample_count : 6;
u64 layout_blob : 15;
u64 input_attachments_mask : 5;
};
renderpass_key_blob(u64 encoded_) : encoded(encoded_)
{}
// Encoders
inline void set_layout(u32 index, VkImageLayout layout)
{
switch (layout)
{
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_GENERAL:
layout_blob |= encode_layout(layout) << (index * 3);
break;
default:
fmt::throw_exception("Unsupported image layout 0x%x", static_cast<u32>(layout));
}
}
inline void set_input_attachment(u32 index)
{
input_attachments_mask |= (1ull << index);
}
inline void set_format(VkFormat format)
{
switch (format)
{
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
key |= (format_code << 8);
depth_format = static_cast<u64>(format);
break;
default:
key |= format_code;
color_format = static_cast<u64>(format);
break;
}
switch (const auto layout = surface->current_layout)
{
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_GENERAL:
key |= (u64(layout) << layout_offset);
layout_offset += 3;
break;
default:
fmt::throw_exception("Unsupported image layout 0x%x", static_cast<u32>(layout));
}
}
key |= u64(images[0]->samples()) << 16;
return key;
// Decoders
inline VkSampleCountFlagBits get_sample_count() const
{
return static_cast<VkSampleCountFlagBits>(sample_count);
}
inline VkFormat get_color_format() const
{
return static_cast<VkFormat>(color_format);
}
inline VkFormat get_depth_format() const
{
return static_cast<VkFormat>(depth_format);
}
std::vector<VkAttachmentReference> get_input_attachments() const
{
if (input_attachments_mask == 0) [[likely]]
{
return {};
}
std::vector<VkAttachmentReference> result;
for (u32 i = 0; i < 5; ++i)
{
if (input_attachments_mask & (1ull << i))
{
const auto layout = decode_layout((layout_blob >> (i * 3)) & 0x7);
result.push_back({i, layout});
}
}
return result;
}
std::vector<VkImageLayout> get_image_layouts() const
{
std::vector<VkImageLayout> result;
for (u32 i = 0, layout_offset = 0; i < 5; ++i, layout_offset += 3)
{
if (const auto layout = VkImageLayout((layout_blob >> layout_offset) & 0x7))
{
result.push_back(layout);
}
else
{
break;
}
}
return result;
}
};
u64 get_renderpass_key(const std::vector<vk::image*>& images, const std::vector<u8>& input_attachment_ids)
{
renderpass_key_blob key(0);
for (u32 i = 0; i < ::size32(images); ++i)
{
const auto& surface = images[i];
key.set_format(surface->format());
key.set_layout(i, surface->current_layout);
}
for (const auto& ref_id : input_attachment_ids)
{
key.set_input_attachment(ref_id);
}
key.sample_count = images[0]->samples();
return key.encoded;
}
u64 get_renderpass_key(const std::vector<vk::image*>& images, u64 previous_key)
{
// Partial update; assumes compatible renderpass keys
const u64 layout_mask = (0x7FFFull << 22);
renderpass_key_blob key(previous_key);
key.layout_blob = 0;
u64 key = previous_key & ~layout_mask;
u64 layout_offset = 22;
for (const auto &surface : images)
for (u32 i = 0; i < ::size32(images); ++i)
{
switch (const auto layout = surface->current_layout)
{
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_GENERAL:
key |= (u64(layout) << layout_offset);
layout_offset += 3;
break;
default:
fmt::throw_exception("Unsupported image layout 0x%x", static_cast<u32>(layout));
}
key.set_layout(i, images[i]->current_layout);
}
return key;
return key.encoded;
}
u64 get_renderpass_key(VkFormat surface_format)
{
u64 key = (1ull << 16);
renderpass_key_blob key(0);
key.sample_count = 1;
switch (surface_format)
{
@ -97,16 +207,16 @@ namespace vk
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
key |= (u64(surface_format) << 8);
key |= (u64(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) << 22);
key.depth_format = static_cast<u64>(surface_format);
key.layout_blob = static_cast<u64>(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
break;
default:
key |= u64(surface_format);
key |= (u64(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) << 22);
key.color_format = static_cast<u64>(surface_format);
key.layout_blob = static_cast<u64>(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
break;
}
return key;
return key.encoded;
}
VkRenderPass get_renderpass(VkDevice dev, u64 renderpass_key)
@ -132,38 +242,24 @@ namespace vk
}
// Decode
VkSampleCountFlagBits samples = VkSampleCountFlagBits((renderpass_key >> 16) & 0xF);
renderpass_key_blob key(renderpass_key);
VkSampleCountFlagBits samples = static_cast<VkSampleCountFlagBits>(key.sample_count);
std::vector<VkImageLayout> rtv_layouts;
VkImageLayout dsv_layout;
u64 layout_offset = 22;
for (int n = 0; n < 5; ++n)
{
const VkImageLayout layout = VkImageLayout((renderpass_key >> layout_offset) & 0x7);
layout_offset += 3;
VkFormat color_format = static_cast<VkFormat>(key.color_format);
VkFormat depth_format = static_cast<VkFormat>(key.depth_format);
if (layout)
{
rtv_layouts.push_back(layout);
}
else
{
break;
}
}
VkFormat color_format = VkFormat(renderpass_key & 0xFF);
VkFormat depth_format = VkFormat((renderpass_key >> 8) & 0xFF);
std::vector<VkAttachmentDescription> attachments = {};
std::vector<VkAttachmentReference> attachment_references;
rtv_layouts = key.get_image_layouts();
if (depth_format)
{
dsv_layout = rtv_layouts.back();
rtv_layouts.pop_back();
}
std::vector<VkAttachmentDescription> attachments = {};
std::vector<VkAttachmentReference> attachment_references;
u32 attachment_count = 0;
for (const auto &layout : rtv_layouts)
{
@ -203,9 +299,16 @@ namespace vk
subpass.pColorAttachments = attachment_count? attachment_references.data() : nullptr;
subpass.pDepthStencilAttachment = depth_format? &attachment_references.back() : nullptr;
const auto input_attachments = key.get_input_attachments();
if (!input_attachments.empty())
{
subpass.inputAttachmentCount = ::size32(input_attachments);
subpass.pInputAttachments = input_attachments.data();
}
VkRenderPassCreateInfo rp_info = {};
rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
rp_info.attachmentCount = static_cast<u32>(attachments.size());
rp_info.attachmentCount = ::size32(attachments);
rp_info.pAttachments = attachments.data();
rp_info.subpassCount = 1;
rp_info.pSubpasses = &subpass;

View File

@ -7,7 +7,7 @@ namespace vk
{
class image;
u64 get_renderpass_key(const std::vector<vk::image*>& images);
u64 get_renderpass_key(const std::vector<vk::image*>& images, const std::vector<u8>& input_attachment_ids = {});
u64 get_renderpass_key(const std::vector<vk::image*>& images, u64 previous_key);
u64 get_renderpass_key(VkFormat surface_format);
VkRenderPass get_renderpass(VkDevice dev, u64 renderpass_key);

View File

@ -98,7 +98,7 @@ namespace rsx
sample_layout = surface_sample_layout::null;
}
VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
if (samples == 1) [[likely]]
{
usage_flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;