vk: Propagate more information to the driver

- Pass "correct" layout to descriptors
- TODO: Fix renderpass attachment descriptors which are inadvertently doing silent transitions
This commit is contained in:
kd-11 2019-05-20 10:27:09 +03:00 committed by kd-11
parent c3b234f972
commit 46ba53f122
5 changed files with 63 additions and 38 deletions

View file

@ -1757,6 +1757,20 @@ void VKGSRender::end()
//Requires update, copy subresource
view = m_texture_cache.create_temporary_subresource(*m_current_command_buffer, sampler_state->external_subresource_desc);
}
else
{
switch (view->image()->current_layout)
{
default:
//case VK_IMAGE_LAYOUT_GENERAL:
//case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
break;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
verify(HERE), sampler_state->upload_context == rsx::texture_upload_context::blit_engine_dst;
view->image()->change_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
break;
}
}
}
if (LIKELY(view))
@ -1792,14 +1806,14 @@ void VKGSRender::end()
}
else
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set);
if (current_fragment_program.redirected_textures & (1 << i))
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set,
@ -1815,7 +1829,7 @@ void VKGSRender::end()
{
if (!rsx::method_registers.vertex_textures[i].enabled())
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_vertex_program,
m_current_frame->descriptor_set);
@ -1835,10 +1849,22 @@ void VKGSRender::end()
if (!image_ptr)
{
LOG_ERROR(RSX, "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), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, rsx::constants::vertex_texture_names[i], m_current_frame->descriptor_set);
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, rsx::constants::vertex_texture_names[i], m_current_frame->descriptor_set);
continue;
}
switch (image_ptr->image()->current_layout)
{
default:
//case VK_IMAGE_LAYOUT_GENERAL:
//case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
break;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
verify(HERE), sampler_state->upload_context == rsx::texture_upload_context::blit_engine_dst;
image_ptr->image()->change_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
break;
}
m_program->bind_uniform({ vs_sampler_handles[i]->value, image_ptr->value, image_ptr->image()->current_layout },
i,
::glsl::program_domain::glsl_vertex_program,
@ -2265,9 +2291,14 @@ void VKGSRender::clear_surface(u32 mask)
{
if (require_mem_load) rtt->write_barrier(*m_current_command_buffer);
vk::insert_texture_barrier(*m_current_command_buffer, rtt);
// Add a barrier to ensure previous writes are visible; also transitions into GENERAL layout
const auto old_layout = rtt->current_layout;
vk::insert_texture_barrier(*m_current_command_buffer, rtt, VK_IMAGE_LAYOUT_GENERAL);
m_attachment_clear_pass->run(*m_current_command_buffer, rtt,
region.rect, renderpass, m_framebuffers_to_clean);
rtt->change_layout(*m_current_command_buffer, old_layout);
}
else
fmt::throw_exception("Unreachable" HERE);

View file

@ -152,18 +152,16 @@ namespace vk
return g_null_sampler;
}
VkImageView null_image_view(vk::command_buffer &cmd)
vk::image_view* null_image_view(vk::command_buffer &cmd)
{
if (g_null_image_view)
return g_null_image_view->value;
return g_null_image_view.get();
g_null_texture.reset(new 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.reset(new image_view(*g_current_renderer, g_null_texture->value, VK_IMAGE_VIEW_TYPE_2D,
VK_FORMAT_B8G8R8A8_UNORM, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}));
g_null_image_view.reset(new image_view(*g_current_renderer, g_null_texture.get()));
// Initialize memory to transparent black
VkClearColorValue clear_color = {};
@ -173,7 +171,7 @@ namespace vk
// Prep for shader access
change_image_layout(cmd, g_null_texture.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
return g_null_image_view->value;
return g_null_image_view.get();
}
vk::image* get_typeless_helper(VkFormat format, u32 requested_width, u32 requested_height)
@ -562,7 +560,7 @@ namespace vk
image->current_layout = new_layout;
}
void insert_texture_barrier(VkCommandBuffer cmd, VkImage image, VkImageLayout layout, VkImageSubresourceRange range)
void insert_texture_barrier(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range)
{
// NOTE: Sampling from an attachment in ATTACHMENT_OPTIMAL layout on some hw ends up with garbage output
// Transition to GENERAL if this resource is both input and output
@ -573,7 +571,7 @@ namespace vk
VkPipelineStageFlags src_stage;
if (range.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
{
if (!rsx::method_registers.color_write_enabled() && layout == VK_IMAGE_LAYOUT_GENERAL)
if (!rsx::method_registers.color_write_enabled() && current_layout == new_layout)
{
// Nothing to do
return;
@ -584,7 +582,7 @@ namespace vk
}
else
{
if (!rsx::method_registers.depth_write_enabled() && layout == VK_IMAGE_LAYOUT_GENERAL)
if (!rsx::method_registers.depth_write_enabled() && current_layout == new_layout)
{
// Nothing to do
return;
@ -596,8 +594,8 @@ namespace vk
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
barrier.oldLayout = layout;
barrier.newLayout = new_layout;
barrier.oldLayout = current_layout;
barrier.image = image;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@ -608,10 +606,10 @@ namespace vk
vkCmdPipelineBarrier(cmd, src_stage, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
}
void insert_texture_barrier(VkCommandBuffer cmd, vk::image *image)
void insert_texture_barrier(VkCommandBuffer cmd, vk::image *image, VkImageLayout new_layout)
{
insert_texture_barrier(cmd, image->value, image->current_layout, { image->aspect(), 0, 1, 0, 1 });
image->current_layout = VK_IMAGE_LAYOUT_GENERAL;
insert_texture_barrier(cmd, image->value, image->current_layout, new_layout, { image->aspect(), 0, 1, 0, 1 });
image->current_layout = new_layout;
}
void enter_uninterruptible()

View file

@ -88,6 +88,7 @@ namespace vk
class physical_device;
class command_buffer;
class image;
struct image_view;
struct buffer;
struct data_heap;
class mem_allocator_base;
@ -116,7 +117,7 @@ namespace vk
VkImageAspectFlags get_aspect_flags(VkFormat format);
VkSampler null_sampler();
VkImageView null_image_view(vk::command_buffer&);
image_view* null_image_view(vk::command_buffer&);
image* get_typeless_helper(VkFormat format, u32 requested_width, u32 requested_height);
buffer* get_scratch_buffer();
@ -166,8 +167,8 @@ namespace vk
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 layout, VkImageSubresourceRange range);
void insert_texture_barrier(VkCommandBuffer cmd, vk::image *image);
void insert_texture_barrier(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range);
void insert_texture_barrier(VkCommandBuffer cmd, vk::image *image, VkImageLayout new_layout);
void insert_buffer_memory_barrier(VkCommandBuffer cmd, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize length,
VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage, VkAccessFlags src_mask, VkAccessFlags dst_mask);

View file

@ -219,7 +219,7 @@ namespace vk
return result;
}
void load_program(vk::command_buffer cmd, VkRenderPass pass, const std::vector<VkImageView>& src)
void load_program(vk::command_buffer cmd, VkRenderPass pass, const std::vector<vk::image_view*>& src)
{
vk::glsl::program *program = nullptr;
auto found = m_program_cache.find(pass);
@ -252,7 +252,7 @@ namespace vk
for (int n = 0; n < src.size(); ++n)
{
VkDescriptorImageInfo info = { m_sampler->value, src[n], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
VkDescriptorImageInfo info = { m_sampler->value, src[n]->value, src[n]->image()->current_layout };
program->bind_uniform(info, "fs" + std::to_string(n), m_descriptor_set);
}
@ -360,7 +360,7 @@ namespace vk
vkCmdSetScissor(cmd, 0, 1, &vs);
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::framebuffer* fbo, const std::vector<VkImageView>& src, VkRenderPass render_pass)
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::framebuffer* fbo, const std::vector<vk::image_view*>& src, VkRenderPass render_pass)
{
load_program(cmd, render_pass, src);
set_up_viewport(cmd, w, h);
@ -379,7 +379,7 @@ namespace vk
vkCmdEndRenderPass(cmd);
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, const std::vector<VkImageView>& src, VkRenderPass render_pass, std::list<std::unique_ptr<vk::framebuffer_holder>>& framebuffer_resources)
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, const std::vector<vk::image_view*>& src, VkRenderPass render_pass, std::list<std::unique_ptr<vk::framebuffer_holder>>& framebuffer_resources)
{
vk::framebuffer *fbo = get_framebuffer(target, render_pass, framebuffer_resources);
@ -388,15 +388,10 @@ namespace vk
static_cast<vk::framebuffer_holder*>(fbo)->release();
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, VkImageView src, VkRenderPass render_pass, std::list<std::unique_ptr<vk::framebuffer_holder>>& framebuffer_resources)
{
std::vector<VkImageView> views = { src };
run(cmd, w, h, target, views, render_pass, framebuffer_resources);
}
void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, vk::image_view* src, VkRenderPass render_pass, std::list<std::unique_ptr<vk::framebuffer_holder>>& framebuffer_resources)
{
run(cmd, w, h, target, src->value, render_pass, framebuffer_resources);
std::vector<vk::image_view*> views = { src };
run(cmd, w, h, target, views, render_pass, framebuffer_resources);
}
};
@ -821,13 +816,13 @@ namespace vk
break;
case rsx::overlays::image_resource_id::font_file:
m_texture_type = 2;
src = find_font(command.config.font_ref, cmd, upload_heap)->value;
src = find_font(command.config.font_ref, cmd, upload_heap);
break;
case rsx::overlays::image_resource_id::raw_image:
src = find_temp_image((rsx::overlays::image_info*)command.config.external_data_ref, cmd, upload_heap, ui.uid)->value;
src = find_temp_image((rsx::overlays::image_info*)command.config.external_data_ref, cmd, upload_heap, ui.uid);
break;
default:
src = view_cache[command.config.texture_ref]->value;
src = view_cache[command.config.texture_ref].get();
break;
}
@ -938,7 +933,7 @@ namespace vk
region = rect;
overlay_pass::run(cmd, target->width(), target->height(), target,
target->get_view(0xAAE4, rsx::default_remap_vector)->value,
target->get_view(0xAAE4, rsx::default_remap_vector),
render_pass, framebuffer_resources);
}
};

View file

@ -1043,7 +1043,7 @@ namespace vk
void insert_texture_barrier(vk::command_buffer& cmd, vk::image* tex) override
{
vk::insert_texture_barrier(cmd, tex);
vk::insert_texture_barrier(cmd, tex, VK_IMAGE_LAYOUT_GENERAL);
}
bool render_target_format_is_compatible(vk::image* tex, u32 gcm_format) override