mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-14 02:38:37 +12:00
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:
parent
c3b234f972
commit
46ba53f122
5 changed files with 63 additions and 38 deletions
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue