mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
vk: Refactor renderpass management
- Ensures the current renderpass matches the image properties even when a cyclic reference is detected - Solves SDK debug output error spam due to mismatching layouts and renderpasses
This commit is contained in:
parent
c348fec84b
commit
507ec8252b
12 changed files with 322 additions and 248 deletions
|
@ -1925,7 +1925,7 @@ namespace rsx
|
|||
f32 scale_x, f32 scale_y,
|
||||
rsx::texture_dimension_extended extended_dimension,
|
||||
u32 encoded_remap, const texture_channel_remap_t& decoded_remap,
|
||||
bool assume_bound = true)
|
||||
bool surface_is_rop_target)
|
||||
{
|
||||
texptr->read_barrier(cmd);
|
||||
|
||||
|
@ -1963,7 +1963,7 @@ namespace rsx
|
|||
internal_height = 1;
|
||||
}
|
||||
|
||||
if ((assume_bound && g_cfg.video.strict_rendering_mode) ||
|
||||
if ((surface_is_rop_target && g_cfg.video.strict_rendering_mode) ||
|
||||
internal_width < surface_width ||
|
||||
internal_height < surface_height ||
|
||||
force_convert)
|
||||
|
@ -1971,19 +1971,19 @@ namespace rsx
|
|||
const auto scaled_w = rsx::apply_resolution_scale(internal_width, true);
|
||||
const auto scaled_h = rsx::apply_resolution_scale(internal_height, true);
|
||||
|
||||
const auto command = assume_bound ? deferred_request_command::copy_image_dynamic : deferred_request_command::copy_image_static;
|
||||
const auto command = surface_is_rop_target ? deferred_request_command::copy_image_dynamic : deferred_request_command::copy_image_static;
|
||||
return { texptr->get_surface(), command, texaddr, format, 0, 0, scaled_w, scaled_h, 1,
|
||||
texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y,
|
||||
extended_dimension, decoded_remap };
|
||||
}
|
||||
|
||||
if (assume_bound)
|
||||
if (surface_is_rop_target)
|
||||
{
|
||||
insert_texture_barrier(cmd, texptr);
|
||||
}
|
||||
|
||||
return{ texptr->get_view(encoded_remap, decoded_remap), texture_upload_context::framebuffer_storage,
|
||||
is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, assume_bound };
|
||||
is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, surface_is_rop_target };
|
||||
}
|
||||
|
||||
const auto scaled_w = rsx::apply_resolution_scale(internal_width, true);
|
||||
|
@ -2136,7 +2136,7 @@ namespace rsx
|
|||
check_framebuffer_resource(cmd, texptr, tex_width, tex_height, depth, tex_pitch, extended_dimension))
|
||||
{
|
||||
return process_framebuffer_resource_fast(cmd, texptr, texaddr, format, tex_width, tex_height, depth,
|
||||
scale_x, scale_y, extended_dimension, tex.remap(), tex.decoded_remap());
|
||||
scale_x, scale_y, extended_dimension, tex.remap(), tex.decoded_remap(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "../Common/BufferUtils.h"
|
||||
#include "VKFormats.h"
|
||||
#include "VKCommonDecompiler.h"
|
||||
#include "VKRenderPass.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -159,63 +160,6 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
/** Maps color_format, depth_stencil_format and color count to an int as below :
|
||||
* idx = color_count + 5 * depth_stencil_idx + 15 * color_format_idx
|
||||
* This should perform a 1:1 mapping
|
||||
*/
|
||||
|
||||
size_t get_render_pass_location(VkFormat color_format, VkFormat depth_stencil_format, u8 color_count)
|
||||
{
|
||||
size_t color_format_idx = 0;
|
||||
size_t depth_format_idx = 0;
|
||||
|
||||
verify(HERE), color_count < 5;
|
||||
|
||||
switch (color_format)
|
||||
{
|
||||
case VK_FORMAT_R5G6B5_UNORM_PACK16:
|
||||
color_format_idx = 0;
|
||||
break;
|
||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||
color_format_idx = 1;
|
||||
break;
|
||||
case VK_FORMAT_R16G16B16A16_SFLOAT:
|
||||
color_format_idx = 2;
|
||||
break;
|
||||
case VK_FORMAT_R32G32B32A32_SFLOAT:
|
||||
color_format_idx = 3;
|
||||
break;
|
||||
case VK_FORMAT_R8_UNORM:
|
||||
color_format_idx = 4;
|
||||
break;
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
color_format_idx = 5;
|
||||
break;
|
||||
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
color_format_idx = 6;
|
||||
break;
|
||||
case VK_FORMAT_R32_SFLOAT:
|
||||
color_format_idx = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (depth_stencil_format)
|
||||
{
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
depth_format_idx = 0;
|
||||
break;
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
depth_format_idx = 1;
|
||||
break;
|
||||
case VK_FORMAT_UNDEFINED:
|
||||
depth_format_idx = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return color_count + 5 * depth_format_idx + 5 * 3 * color_format_idx;
|
||||
}
|
||||
|
||||
VkLogicOp get_logic_op(rsx::logic_op op)
|
||||
{
|
||||
switch (op)
|
||||
|
@ -326,111 +270,8 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
VkRenderPass precompute_render_pass(VkDevice dev, VkFormat color_format, u8 number_of_color_surface, VkFormat depth_format)
|
||||
{
|
||||
// Some driver crashes when using empty render pass
|
||||
if (number_of_color_surface == 0 && depth_format == VK_FORMAT_UNDEFINED)
|
||||
return nullptr;
|
||||
/* Describe a render pass and framebuffer attachments */
|
||||
std::vector<VkAttachmentDescription> attachments = {};
|
||||
std::vector<VkAttachmentReference> attachment_references;
|
||||
|
||||
VkAttachmentDescription color_attachment_description = {};
|
||||
color_attachment_description.format = color_format;
|
||||
color_attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
color_attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
color_attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
color_attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
color_attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
color_attachment_description.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
color_attachment_description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
for (u32 i = 0; i < number_of_color_surface; ++i)
|
||||
{
|
||||
attachments.push_back(color_attachment_description);
|
||||
attachment_references.push_back({ i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL });
|
||||
}
|
||||
|
||||
if (depth_format != VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
VkAttachmentDescription depth_attachment_description = {};
|
||||
depth_attachment_description.format = depth_format;
|
||||
depth_attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
depth_attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depth_attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
depth_attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depth_attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
depth_attachment_description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
depth_attachment_description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
attachments.push_back(depth_attachment_description);
|
||||
|
||||
attachment_references.push_back({ number_of_color_surface, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL });
|
||||
}
|
||||
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = number_of_color_surface;
|
||||
subpass.pColorAttachments = number_of_color_surface > 0 ? attachment_references.data() : nullptr;
|
||||
subpass.pDepthStencilAttachment = depth_format != VK_FORMAT_UNDEFINED ? &attachment_references.back() : nullptr;
|
||||
|
||||
VkRenderPassCreateInfo rp_info = {};
|
||||
rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
rp_info.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||
rp_info.pAttachments = attachments.data();
|
||||
rp_info.subpassCount = 1;
|
||||
rp_info.pSubpasses = &subpass;
|
||||
rp_info.pDependencies = nullptr;
|
||||
rp_info.dependencyCount = 0;
|
||||
|
||||
VkRenderPass result;
|
||||
CHECK_RESULT(vkCreateRenderPass(dev, &rp_info, NULL, &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
std::array<VkRenderPass, 120> get_precomputed_render_passes(VkPhysicalDevice gpu, VkDevice dev, const vk::gpu_formats_support &gpu_format_support)
|
||||
{
|
||||
std::array<VkRenderPass, 120> result = {};
|
||||
VkImageFormatProperties props = {};
|
||||
|
||||
const std::array<VkFormat, 3> depth_format_list = { VK_FORMAT_UNDEFINED, VK_FORMAT_D16_UNORM, gpu_format_support.d24_unorm_s8 ? VK_FORMAT_D24_UNORM_S8_UINT : VK_FORMAT_D32_SFLOAT_S8_UINT };
|
||||
const std::array<VkFormat, 8> color_format_list = { VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_R32_SFLOAT };
|
||||
|
||||
for (const VkFormat &color_format : color_format_list)
|
||||
{
|
||||
VkResult support = vkGetPhysicalDeviceImageFormatProperties(gpu, color_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &props);
|
||||
if (support != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR(RSX, "Format 0x%x is not supported for color target usage by your GPU driver. Crashes may arise.", (u32)color_format);
|
||||
verify(HERE), support == VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const VkFormat &depth_stencil_format : depth_format_list)
|
||||
{
|
||||
if (depth_stencil_format != VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
VkResult support = vkGetPhysicalDeviceImageFormatProperties(gpu, depth_stencil_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &props);
|
||||
if (support != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR(RSX, "Format 0x%x is not supported for depth/stencil target usage by your GPU driver. Crashes may arise.", (u32)depth_stencil_format);
|
||||
verify(HERE), support == VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (u8 number_of_draw_buffer = 0; number_of_draw_buffer <= 4; number_of_draw_buffer++)
|
||||
{
|
||||
size_t idx = vk::get_render_pass_location(color_format, depth_stencil_format, number_of_draw_buffer);
|
||||
result[idx] = precompute_render_pass(dev, color_format, number_of_draw_buffer, depth_stencil_format);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::tuple<VkPipelineLayout, VkDescriptorSetLayout> get_shared_pipeline_layout(VkDevice dev)
|
||||
{
|
||||
std::array<VkDescriptorSetLayoutBinding, VK_NUM_DESCRIPTOR_BINDINGS> bindings = {};
|
||||
|
@ -625,7 +466,6 @@ VKGSRender::VKGSRender() : GSRender()
|
|||
m_secondary_command_buffer.access_hint = vk::command_buffer::access_type_hint::all;
|
||||
|
||||
//Precalculated stuff
|
||||
m_render_passes = get_precomputed_render_passes(m_device->gpu(), *m_device, m_device->get_formats_support());
|
||||
std::tie(pipeline_layout, descriptor_layouts) = get_shared_pipeline_layout(*m_device);
|
||||
|
||||
//Occlusion
|
||||
|
@ -677,9 +517,9 @@ VKGSRender::VKGSRender() : GSRender()
|
|||
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
size_t idx = vk::get_render_pass_location( m_swapchain->get_surface_format(), VK_FORMAT_UNDEFINED, 1);
|
||||
auto key = vk::get_renderpass_key(m_swapchain->get_surface_format());
|
||||
m_text_writer.reset(new vk::text_writer());
|
||||
m_text_writer->init(*m_device, m_render_passes[idx]);
|
||||
m_text_writer->init(*m_device, vk::get_renderpass(*m_device, key));
|
||||
}
|
||||
|
||||
m_depth_converter.reset(new vk::depth_convert_pass());
|
||||
|
@ -688,7 +528,7 @@ VKGSRender::VKGSRender() : GSRender()
|
|||
m_attachment_clear_pass.reset(new vk::attachment_clear_pass());
|
||||
m_attachment_clear_pass->create(*m_device);
|
||||
|
||||
m_prog_buffer.reset(new VKProgramBuffer(m_render_passes.data()));
|
||||
m_prog_buffer.reset(new VKProgramBuffer());
|
||||
|
||||
if (g_cfg.video.disable_vertex_cache)
|
||||
m_vertex_cache.reset(new vk::null_vertex_cache());
|
||||
|
@ -787,11 +627,6 @@ VKGSRender::~VKGSRender()
|
|||
|
||||
m_draw_fbo.reset();
|
||||
|
||||
//Render passes
|
||||
for (auto &render_pass : m_render_passes)
|
||||
if (render_pass)
|
||||
vkDestroyRenderPass(*m_device, render_pass, nullptr);
|
||||
|
||||
//Textures
|
||||
m_rtts.destroy();
|
||||
m_texture_cache.destroy();
|
||||
|
@ -1304,9 +1139,11 @@ void VKGSRender::begin_render_pass()
|
|||
if (m_render_pass_open)
|
||||
return;
|
||||
|
||||
const auto renderpass = (m_cached_renderpass)? m_cached_renderpass : vk::get_renderpass(*m_device, m_current_renderpass_key);
|
||||
|
||||
VkRenderPassBeginInfo rp_begin = {};
|
||||
rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
rp_begin.renderPass = m_draw_fbo->info.renderPass;
|
||||
rp_begin.renderPass = renderpass;
|
||||
rp_begin.framebuffer = m_draw_fbo->value;
|
||||
rp_begin.renderArea.offset.x = 0;
|
||||
rp_begin.renderArea.offset.y = 0;
|
||||
|
@ -1496,17 +1333,18 @@ void VKGSRender::end()
|
|||
ds->old_contents.source->info.format == VK_FORMAT_B8G8R8A8_UNORM &&
|
||||
rsx::pitch_compatible(ds, vk::as_rtt(ds->old_contents.source)))
|
||||
{
|
||||
auto rp = vk::get_render_pass_location(VK_FORMAT_UNDEFINED, ds->info.format, 0);
|
||||
auto render_pass = m_render_passes[rp];
|
||||
auto key = vk::get_renderpass_key(ds->info.format);
|
||||
auto render_pass = vk::get_renderpass(*m_device, key);
|
||||
verify("Usupported renderpass configuration" HERE), render_pass != VK_NULL_HANDLE;
|
||||
|
||||
VkClearDepthStencilValue clear = { 1.f, 0xFF };
|
||||
VkImageSubresourceRange range = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1 };
|
||||
|
||||
// Clear explicitly before starting the inheritance transfer
|
||||
vk::change_image_layout(*m_current_command_buffer, ds, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
|
||||
const bool preinitialized = (ds->current_layout == VK_IMAGE_LAYOUT_GENERAL);
|
||||
if (!preinitialized) ds->push_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
vkCmdClearDepthStencilImage(*m_current_command_buffer, ds->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear, 1, &range);
|
||||
vk::change_image_layout(*m_current_command_buffer, ds, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
|
||||
if (!preinitialized) ds->pop_layout(*m_current_command_buffer);
|
||||
|
||||
// TODO: Stencil transfer
|
||||
ds->old_contents.init_transfer(ds);
|
||||
|
@ -1524,16 +1362,14 @@ void VKGSRender::end()
|
|||
{
|
||||
std::lock_guard lock(m_sampler_mutex);
|
||||
bool update_framebuffer_sourced = false;
|
||||
bool check_for_cyclic_refs = false;
|
||||
|
||||
if (surface_store_tag != m_rtts.cache_tag)
|
||||
if (UNLIKELY(surface_store_tag != m_rtts.cache_tag))
|
||||
{
|
||||
update_framebuffer_sourced = true;
|
||||
surface_store_tag = m_rtts.cache_tag;
|
||||
}
|
||||
|
||||
const bool check_for_cyclic_refs = m_render_pass_is_cyclic;
|
||||
m_render_pass_is_cyclic = false;
|
||||
|
||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
{
|
||||
if (!fs_sampler_state[i])
|
||||
|
@ -1549,6 +1385,11 @@ void VKGSRender::end()
|
|||
check_heap_status(VK_HEAP_CHECK_TEXTURE_UPLOAD_STORAGE);
|
||||
*sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, rsx::method_registers.fragment_textures[i], m_rtts);
|
||||
|
||||
if (sampler_state->is_cyclic_reference)
|
||||
{
|
||||
check_for_cyclic_refs |= true;
|
||||
}
|
||||
|
||||
bool replace = !fs_sampler_handles[i];
|
||||
VkFilter min_filter, mag_filter;
|
||||
VkSamplerMipmapMode mip_mode;
|
||||
|
@ -1644,7 +1485,6 @@ void VKGSRender::end()
|
|||
}
|
||||
|
||||
m_textures_dirty[i] = false;
|
||||
m_render_pass_is_cyclic |= sampler_state->is_cyclic_reference;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1663,6 +1503,11 @@ void VKGSRender::end()
|
|||
check_heap_status(VK_HEAP_CHECK_TEXTURE_UPLOAD_STORAGE);
|
||||
*sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, rsx::method_registers.vertex_textures[i], m_rtts);
|
||||
|
||||
if (sampler_state->is_cyclic_reference)
|
||||
{
|
||||
check_for_cyclic_refs |= true;
|
||||
}
|
||||
|
||||
bool replace = !vs_sampler_handles[i];
|
||||
const VkBool32 unnormalized_coords = !!(rsx::method_registers.vertex_textures[i].format() & CELL_GCM_TEXTURE_UN);
|
||||
const auto min_lod = (f32)rsx::method_registers.vertex_textures[i].min_lod();
|
||||
|
@ -1692,30 +1537,19 @@ void VKGSRender::end()
|
|||
*sampler_state = {};
|
||||
|
||||
m_vertex_textures_dirty[i] = false;
|
||||
m_render_pass_is_cyclic |= sampler_state->is_cyclic_reference;
|
||||
}
|
||||
}
|
||||
|
||||
m_samplers_dirty.store(false);
|
||||
|
||||
if (check_for_cyclic_refs && !m_render_pass_is_cyclic)
|
||||
if (check_for_cyclic_refs)
|
||||
{
|
||||
// Reverse texture barriers for optimal performance
|
||||
for (unsigned i = m_rtts.m_bound_render_targets_config.first, count = 0;
|
||||
count < m_rtts.m_bound_render_targets_config.second;
|
||||
++i, ++count)
|
||||
// Regenerate renderpass key
|
||||
if (const auto key = vk::get_renderpass_key(m_fbo_images, m_current_renderpass_key);
|
||||
key != m_current_renderpass_key)
|
||||
{
|
||||
if (auto surface = m_rtts.m_bound_render_targets[i].second;
|
||||
surface->current_layout == VK_IMAGE_LAYOUT_GENERAL)
|
||||
{
|
||||
surface->change_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto surface = m_rtts.m_bound_depth_stencil.second;
|
||||
surface && surface->current_layout == VK_IMAGE_LAYOUT_GENERAL)
|
||||
{
|
||||
surface->change_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
m_current_renderpass_key = key;
|
||||
m_cached_renderpass = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2282,11 +2116,7 @@ void VKGSRender::clear_surface(u32 mask)
|
|||
color_clear_values.color.float32[3]
|
||||
};
|
||||
|
||||
const auto fbo_format = vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first;
|
||||
const auto rp_index = vk::get_render_pass_location(fbo_format, VK_FORMAT_UNDEFINED, 1);
|
||||
const auto renderpass = m_render_passes[rp_index];
|
||||
verify("Usupported renderpass configuration" HERE), renderpass != VK_NULL_HANDLE;
|
||||
|
||||
VkRenderPass renderpass = VK_NULL_HANDLE;
|
||||
m_attachment_clear_pass->update_config(colormask, clear_color);
|
||||
|
||||
for (const auto &index : m_draw_buffers)
|
||||
|
@ -2299,6 +2129,13 @@ void VKGSRender::clear_surface(u32 mask)
|
|||
const auto old_layout = rtt->current_layout;
|
||||
vk::insert_texture_barrier(*m_current_command_buffer, rtt, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
if (!renderpass)
|
||||
{
|
||||
std::vector<vk::image*> surfaces = { rtt };
|
||||
const auto key = vk::get_renderpass_key(surfaces);
|
||||
renderpass = vk::get_renderpass(*m_device, key);
|
||||
}
|
||||
|
||||
m_attachment_clear_pass->run(*m_current_command_buffer, rtt,
|
||||
region.rect, renderpass, m_framebuffers_to_clean);
|
||||
|
||||
|
@ -2784,8 +2621,7 @@ bool VKGSRender::load_program()
|
|||
}
|
||||
}
|
||||
|
||||
properties.render_pass = m_render_passes[m_current_renderpass_id];
|
||||
properties.render_pass_location = (int)m_current_renderpass_id;
|
||||
properties.renderpass_key = m_current_renderpass_key;
|
||||
properties.num_targets = (u32)m_draw_buffers.size();
|
||||
|
||||
vk::enter_uninterruptible();
|
||||
|
@ -3104,16 +2940,14 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
|||
|
||||
//Bind created rtts as current fbo...
|
||||
const auto draw_buffers = rsx::utility::get_rtt_indexes(layout.target);
|
||||
m_draw_buffers.resize(0);
|
||||
|
||||
std::vector<vk::image*> bound_images;
|
||||
bound_images.reserve(5);
|
||||
m_draw_buffers.clear();
|
||||
m_fbo_images.clear();
|
||||
|
||||
for (u8 index : draw_buffers)
|
||||
{
|
||||
if (auto surface = std::get<1>(m_rtts.m_bound_render_targets[index]))
|
||||
{
|
||||
bound_images.push_back(surface);
|
||||
m_fbo_images.push_back(surface);
|
||||
|
||||
m_surface_info[index].address = layout.color_addresses[index];
|
||||
m_surface_info[index].pitch = layout.actual_color_pitch[index];
|
||||
|
@ -3128,7 +2962,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
|||
if (std::get<0>(m_rtts.m_bound_depth_stencil) != 0)
|
||||
{
|
||||
auto ds = std::get<1>(m_rtts.m_bound_depth_stencil);
|
||||
bound_images.push_back(ds);
|
||||
m_fbo_images.push_back(ds);
|
||||
|
||||
m_depth_surface_info.address = layout.zeta_address;
|
||||
m_depth_surface_info.pitch = layout.actual_zeta_pitch;
|
||||
|
@ -3214,8 +3048,8 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
|||
m_rtts.orphaned_surfaces.clear();
|
||||
}
|
||||
|
||||
auto vk_depth_format = (layout.zeta_address == 0) ? VK_FORMAT_UNDEFINED : vk::get_compatible_depth_surface_format(m_device->get_formats_support(), layout.depth_format);
|
||||
m_current_renderpass_id = vk::get_render_pass_location(vk::get_compatible_surface_format(layout.color_format).first, vk_depth_format, (u8)m_draw_buffers.size());
|
||||
m_current_renderpass_key = vk::get_renderpass_key(m_fbo_images);
|
||||
m_cached_renderpass = VK_NULL_HANDLE;
|
||||
|
||||
// Search old framebuffers for this same configuration
|
||||
bool framebuffer_found = false;
|
||||
|
@ -3230,7 +3064,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
|||
|
||||
for (auto &fbo : m_framebuffers_to_clean)
|
||||
{
|
||||
if (fbo->matches(bound_images, fbo_width, fbo_height))
|
||||
if (fbo->matches(m_fbo_images, fbo_width, fbo_height))
|
||||
{
|
||||
m_draw_fbo.swap(fbo);
|
||||
m_draw_fbo->add_ref();
|
||||
|
@ -3273,7 +3107,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
|||
fbo_images.push_back(std::make_unique<vk::image_view>(*m_device, raw->value, VK_IMAGE_VIEW_TYPE_2D, raw->info.format, vk::default_component_map(), subres));
|
||||
}
|
||||
|
||||
VkRenderPass current_render_pass = m_render_passes[m_current_renderpass_id];
|
||||
VkRenderPass current_render_pass = vk::get_renderpass(*m_device, m_current_renderpass_key);
|
||||
verify("Usupported renderpass configuration" HERE), current_render_pass != VK_NULL_HANDLE;
|
||||
|
||||
if (m_draw_fbo)
|
||||
|
@ -3626,9 +3460,9 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
//TODO: Upload raw bytes from cpu for rendering
|
||||
VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
VkClearColorValue clear_black {};
|
||||
vk::change_image_layout(*m_current_command_buffer, m_swapchain->get_image(m_current_frame->present_image), present_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
|
||||
vkCmdClearColorImage(*m_current_command_buffer, m_swapchain->get_image(m_current_frame->present_image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_black, 1, &range);
|
||||
vk::change_image_layout(*m_current_command_buffer, m_swapchain->get_image(m_current_frame->present_image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, present_layout, range);
|
||||
vk::change_image_layout(*m_current_command_buffer, target_image, present_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
|
||||
vkCmdClearColorImage(*m_current_command_buffer, target_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_black, 1, &range);
|
||||
vk::change_image_layout(*m_current_command_buffer, target_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, present_layout, range);
|
||||
}
|
||||
|
||||
std::unique_ptr<vk::framebuffer_holder> direct_fbo;
|
||||
|
@ -3651,8 +3485,8 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
|
||||
vkCmdPipelineBarrier(*m_current_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
size_t idx = vk::get_render_pass_location(m_swapchain->get_surface_format(), VK_FORMAT_UNDEFINED, 1);
|
||||
VkRenderPass single_target_pass = m_render_passes[idx];
|
||||
auto key = vk::get_renderpass_key(m_swapchain->get_surface_format());
|
||||
VkRenderPass single_target_pass = vk::get_renderpass(*m_device, key);
|
||||
verify("Usupported renderpass configuration" HERE), single_target_pass != VK_NULL_HANDLE;
|
||||
|
||||
for (auto It = m_framebuffers_to_clean.begin(); It != m_framebuffers_to_clean.end(); It++)
|
||||
|
|
|
@ -406,8 +406,6 @@ private:
|
|||
std::array<command_buffer_chunk, VK_MAX_ASYNC_CB_COUNT> m_primary_cb_list;
|
||||
command_buffer_chunk* m_current_command_buffer = nullptr;
|
||||
|
||||
std::array<VkRenderPass, 120> m_render_passes;
|
||||
|
||||
VkDescriptorSetLayout descriptor_layouts;
|
||||
VkPipelineLayout pipeline_layout;
|
||||
|
||||
|
@ -468,8 +466,9 @@ private:
|
|||
std::atomic<u64> m_last_sync_event = { 0 };
|
||||
|
||||
bool m_render_pass_open = false;
|
||||
bool m_render_pass_is_cyclic = false;
|
||||
size_t m_current_renderpass_id = 0;
|
||||
u64 m_current_renderpass_key = 0;
|
||||
VkRenderPass m_cached_renderpass = VK_NULL_HANDLE;
|
||||
std::vector<vk::image*> m_fbo_images;
|
||||
|
||||
//Vertex layout
|
||||
rsx::vertex_input_layout m_vertex_layout;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "VKHelpers.h"
|
||||
#include "VKCompute.h"
|
||||
#include "VKRenderPass.h"
|
||||
#include "Utilities/mutex.h"
|
||||
|
||||
namespace vk
|
||||
|
@ -234,6 +235,9 @@ namespace vk
|
|||
|
||||
void destroy_global_resources()
|
||||
{
|
||||
VkDevice dev = *g_current_renderer;
|
||||
vk::clear_renderpass_cache(dev);
|
||||
|
||||
g_null_texture.reset();
|
||||
g_null_image_view.reset();
|
||||
g_scratch_buffer.reset();
|
||||
|
@ -242,9 +246,10 @@ namespace vk
|
|||
g_deleted_typeless_textures.clear();
|
||||
|
||||
if (g_null_sampler)
|
||||
vkDestroySampler(*g_current_renderer, g_null_sampler, nullptr);
|
||||
|
||||
g_null_sampler = nullptr;
|
||||
{
|
||||
vkDestroySampler(dev, g_null_sampler, nullptr);
|
||||
g_null_sampler = nullptr;
|
||||
}
|
||||
|
||||
for (const auto& p : g_compute_tasks)
|
||||
{
|
||||
|
|
|
@ -164,7 +164,6 @@ namespace vk
|
|||
VkFilter filter = VK_FILTER_LINEAR, VkFormat src_format = VK_FORMAT_UNDEFINED, VkFormat dst_format = VK_FORMAT_UNDEFINED);
|
||||
|
||||
std::pair<VkFormat, VkComponentMapping> get_compatible_surface_format(rsx::surface_color_format color_format);
|
||||
size_t get_render_pass_location(VkFormat color_surface_format, VkFormat depth_stencil_format, u8 color_surface_count);
|
||||
|
||||
//Texture barrier applies to a texture to ensure writes to it are finished before any reads are attempted to avoid RAW hazards
|
||||
void insert_texture_barrier(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range);
|
||||
|
@ -1061,6 +1060,11 @@ namespace vk
|
|||
return info.extent.depth;
|
||||
}
|
||||
|
||||
u8 samples() const
|
||||
{
|
||||
return u8(info.samples);
|
||||
}
|
||||
|
||||
VkFormat format() const
|
||||
{
|
||||
return info.format;
|
||||
|
|
|
@ -4,22 +4,22 @@
|
|||
#include "../Common/ProgramStateCache.h"
|
||||
#include "Utilities/hash.h"
|
||||
#include "VKHelpers.h"
|
||||
#include "VKRenderPass.h"
|
||||
|
||||
namespace vk
|
||||
{
|
||||
struct pipeline_props
|
||||
{
|
||||
graphics_pipeline_state state;
|
||||
VkRenderPass render_pass;
|
||||
int num_targets;
|
||||
int render_pass_location;
|
||||
u64 renderpass_key;
|
||||
|
||||
bool operator==(const pipeline_props& other) const
|
||||
{
|
||||
if (memcmp(&state.att_state[0], &other.state.att_state[0], sizeof(VkPipelineColorBlendAttachmentState)))
|
||||
return false;
|
||||
|
||||
if (render_pass_location != other.render_pass_location)
|
||||
if (renderpass_key != other.renderpass_key)
|
||||
return false;
|
||||
|
||||
if (memcmp(&state.rs, &other.state.rs, sizeof(VkPipelineRasterizationStateCreateInfo)))
|
||||
|
@ -162,7 +162,7 @@ struct VKTraits
|
|||
info.layout = common_pipeline_layout;
|
||||
info.basePipelineIndex = -1;
|
||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
info.renderPass = pipelineProperties.render_pass;
|
||||
info.renderPass = vk::get_renderpass(dev, pipelineProperties.renderpass_key);
|
||||
|
||||
CHECK_RESULT(vkCreateGraphicsPipelines(dev, nullptr, 1, &info, NULL, &pipeline));
|
||||
|
||||
|
@ -172,14 +172,9 @@ struct VKTraits
|
|||
}
|
||||
};
|
||||
|
||||
class VKProgramBuffer : public program_state_cache<VKTraits>
|
||||
struct VKProgramBuffer : public program_state_cache<VKTraits>
|
||||
{
|
||||
const VkRenderPass *m_render_pass_data;
|
||||
|
||||
public:
|
||||
VKProgramBuffer(VkRenderPass *renderpass_list)
|
||||
: m_render_pass_data(renderpass_list)
|
||||
{}
|
||||
VKProgramBuffer() = default;
|
||||
|
||||
void clear()
|
||||
{
|
||||
|
@ -206,8 +201,6 @@ public:
|
|||
template <typename... Args>
|
||||
void add_pipeline_entry(RSXVertexProgram &vp, RSXFragmentProgram &fp, vk::pipeline_props &props, Args&& ...args)
|
||||
{
|
||||
props.render_pass = m_render_pass_data[props.render_pass_location];
|
||||
verify("Usupported renderpass configuration" HERE), props.render_pass != VK_NULL_HANDLE;
|
||||
vp.skip_vertex_input_check = true;
|
||||
get_graphics_pipeline(vp, fp, props, false, std::forward<Args>(args)...);
|
||||
}
|
||||
|
|
218
rpcs3/Emu/RSX/VK/VKRenderPass.cpp
Normal file
218
rpcs3/Emu/RSX/VK/VKRenderPass.cpp
Normal file
|
@ -0,0 +1,218 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include "Utilities/mutex.h"
|
||||
#include "VKRenderPass.h"
|
||||
|
||||
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-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)
|
||||
{
|
||||
const auto format_code = u64(surface->format()) & 0xFF;
|
||||
switch (format_code)
|
||||
{
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
key |= (format_code << 8);
|
||||
break;
|
||||
default:
|
||||
key |= format_code;
|
||||
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", (u32)layout);
|
||||
}
|
||||
}
|
||||
|
||||
key |= u64(images[0]->samples()) << 16;
|
||||
return key;
|
||||
}
|
||||
|
||||
u64 get_renderpass_key(const std::vector<vk::image*>& images, u64 previous_key)
|
||||
{
|
||||
// Partial update; assumes compatible renderpass keys
|
||||
const u64 layout_mask = (0x7FFF << 22);
|
||||
|
||||
u64 key = previous_key & ~layout_mask;
|
||||
u64 layout_offset = 22;
|
||||
|
||||
for (const auto &surface : images)
|
||||
{
|
||||
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", (u32)layout);
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
u64 get_renderpass_key(VkFormat surface_format)
|
||||
{
|
||||
u64 key = (1ull << 16);
|
||||
|
||||
switch (surface_format)
|
||||
{
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
key |= u64(surface_format);
|
||||
key |= (u64(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) << 22);
|
||||
break;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
VkRenderPass get_renderpass(VkDevice dev, u64 renderpass_key)
|
||||
{
|
||||
// 99.999% of checks will go through this block once on-disk shader cache has loaded
|
||||
{
|
||||
reader_lock lock(g_renderpass_cache_mutex);
|
||||
|
||||
auto found = g_renderpass_cache.find(renderpass_key);
|
||||
if (found != g_renderpass_cache.end())
|
||||
{
|
||||
return found->second;
|
||||
}
|
||||
}
|
||||
|
||||
std::lock_guard lock(g_renderpass_cache_mutex);
|
||||
|
||||
// Check again
|
||||
auto found = g_renderpass_cache.find(renderpass_key);
|
||||
if (found != g_renderpass_cache.end())
|
||||
{
|
||||
return found->second;
|
||||
}
|
||||
|
||||
// Decode
|
||||
VkSampleCountFlagBits samples = VkSampleCountFlagBits((renderpass_key >> 16) & 0x1F);
|
||||
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;
|
||||
|
||||
if (layout)
|
||||
{
|
||||
rtv_layouts.push_back(layout);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat color_format = VkFormat(renderpass_key & 0xFF);
|
||||
VkFormat depth_format = VkFormat((renderpass_key >> 8) & 0xFF);
|
||||
|
||||
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)
|
||||
{
|
||||
VkAttachmentDescription color_attachment_description = {};
|
||||
color_attachment_description.format = color_format;
|
||||
color_attachment_description.samples = samples;
|
||||
color_attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
color_attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
color_attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
color_attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
color_attachment_description.initialLayout = layout;
|
||||
color_attachment_description.finalLayout = layout;
|
||||
|
||||
attachments.push_back(color_attachment_description);
|
||||
attachment_references.push_back({ attachment_count++, layout });
|
||||
}
|
||||
|
||||
if (depth_format)
|
||||
{
|
||||
VkAttachmentDescription depth_attachment_description = {};
|
||||
depth_attachment_description.format = depth_format;
|
||||
depth_attachment_description.samples = samples;
|
||||
depth_attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depth_attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
depth_attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depth_attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
depth_attachment_description.initialLayout = dsv_layout;
|
||||
depth_attachment_description.finalLayout = dsv_layout;
|
||||
attachments.push_back(depth_attachment_description);
|
||||
|
||||
attachment_references.push_back({ attachment_count, dsv_layout });
|
||||
}
|
||||
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = attachment_count;
|
||||
subpass.pColorAttachments = attachment_count? attachment_references.data() : nullptr;
|
||||
subpass.pDepthStencilAttachment = depth_format? &attachment_references.back() : nullptr;
|
||||
|
||||
VkRenderPassCreateInfo rp_info = {};
|
||||
rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
rp_info.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||
rp_info.pAttachments = attachments.data();
|
||||
rp_info.subpassCount = 1;
|
||||
rp_info.pSubpasses = &subpass;
|
||||
rp_info.pDependencies = nullptr;
|
||||
rp_info.dependencyCount = 0;
|
||||
|
||||
VkRenderPass result;
|
||||
CHECK_RESULT(vkCreateRenderPass(dev, &rp_info, NULL, &result));
|
||||
|
||||
g_renderpass_cache[renderpass_key] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void clear_renderpass_cache(VkDevice dev)
|
||||
{
|
||||
for (const auto &renderpass : g_renderpass_cache)
|
||||
{
|
||||
vkDestroyRenderPass(dev, renderpass.second, nullptr);
|
||||
}
|
||||
|
||||
g_renderpass_cache.clear();
|
||||
}
|
||||
}
|
13
rpcs3/Emu/RSX/VK/VKRenderPass.h
Normal file
13
rpcs3/Emu/RSX/VK/VKRenderPass.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "VKHelpers.h"
|
||||
|
||||
namespace vk
|
||||
{
|
||||
u64 get_renderpass_key(const std::vector<vk::image*>& images);
|
||||
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);
|
||||
|
||||
void clear_renderpass_cache(VkDevice dev);
|
||||
}
|
|
@ -308,6 +308,8 @@ namespace rsx
|
|||
sink->surface_width = prev.width;
|
||||
sink->surface_height = prev.height;
|
||||
sink->queue_tag(address);
|
||||
|
||||
change_image_layout(cmd, sink.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
|
||||
prev.target = sink.get();
|
||||
|
@ -316,8 +318,6 @@ namespace rsx
|
|||
sink->sync_tag();
|
||||
sink->set_old_contents_region(prev, false);
|
||||
sink->last_use_tag = ref->last_use_tag;
|
||||
|
||||
change_image_layout(cmd, sink.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
|
||||
static bool is_compatible_surface(const vk::render_target* surface, const vk::render_target* ref, u16 width, u16 height, u8 /*sample_count*/)
|
||||
|
|
|
@ -253,7 +253,7 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
void init(vk::render_device &dev, VkRenderPass &render_pass)
|
||||
void init(vk::render_device &dev, VkRenderPass render_pass)
|
||||
{
|
||||
verify(HERE), render_pass != VK_NULL_HANDLE;
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<ClInclude Include="Emu\RSX\VK\VKHelpers.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKOverlays.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKProgramBuffer.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKRenderPass.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKRenderTargets.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKTextOut.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKTextureCache.h" />
|
||||
|
@ -44,6 +45,7 @@
|
|||
<ClCompile Include="Emu\RSX\VK\VKGSRender.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKHelpers.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKProgramPipeline.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKRenderPass.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKTexture.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKVertexBuffers.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKVertexProgram.cpp" />
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
<ClInclude Include="Emu\RSX\VK\VKCompute.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\VK\VKRenderPass.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Emu\RSX\VK\VKGSRender.cpp">
|
||||
|
@ -81,5 +84,8 @@
|
|||
<ClCompile Include="Emu\RSX\VK\VKMemAlloc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\VK\VKRenderPass.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Add table
Reference in a new issue