vk: Spec fixups

- Disable DEPTH<->RGBA typeless transfers for now as they require a lot more work to work for all vendors
- Do not allow switching layouts to UNDEFINED/PREINITIALIZED formats
This commit is contained in:
kd-11 2019-01-24 00:58:28 +03:00 committed by kd-11
parent 2163a59649
commit fa9b448686
4 changed files with 37 additions and 17 deletions

View file

@ -593,7 +593,7 @@ void gl::render_target::memory_barrier(gl::command_context& cmd, bool force_init
auto src_texture = static_cast<gl::render_target*>(old_contents);
if (src_texture->get_rsx_pitch() != get_rsx_pitch())
{
LOG_TODO(RSX, "Pitch mismatch, could not transfer inherited memory");
LOG_TRACE(RSX, "Pitch mismatch, could not transfer inherited memory");
return;
}

View file

@ -449,6 +449,9 @@ namespace vk
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
dst_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
break;
case VK_IMAGE_LAYOUT_UNDEFINED:
case VK_IMAGE_LAYOUT_PREINITIALIZED:
fmt::throw_exception("Attempted to transition to an invalid layout");
}
switch (current_layout)

View file

@ -59,12 +59,14 @@ namespace vk
void memory_barrier(vk::command_buffer& cmd, bool force_init = false)
{
if (!old_contents)
// Helper to optionally clear/initialize memory contents depending on barrier type
auto null_transfer_impl = [&]()
{
if (dirty && force_init)
{
// Initialize memory contents if we did not find anything usable
// TODO: Properly sync with Cell
VkImageSubresourceRange range{ attachment_aspect_flag, 0, 1, 0, 1 };
const auto old_layout = current_layout;
@ -84,14 +86,18 @@ namespace vk
change_image_layout(cmd, this, old_layout, range);
on_write();
}
};
if (!old_contents)
{
null_transfer_impl();
return;
}
auto src_texture = static_cast<vk::render_target*>(old_contents);
if (src_texture->get_rsx_pitch() != get_rsx_pitch())
{
LOG_TODO(RSX, "Pitch mismatch, could not transfer inherited memory");
LOG_TRACE(RSX, "Pitch mismatch, could not transfer inherited memory");
return;
}
@ -107,8 +113,15 @@ namespace vk
}
else
{
const bool src_is_depth = !!(vk::get_aspect_flags(src_texture->info.format) & VK_IMAGE_ASPECT_DEPTH_BIT);
const bool dst_is_depth = !!(vk::get_aspect_flags(info.format) & VK_IMAGE_ASPECT_DEPTH_BIT);
const bool src_is_depth = !!(src_texture->attachment_aspect_flag & VK_IMAGE_ASPECT_DEPTH_BIT);
const bool dst_is_depth = !!(attachment_aspect_flag & VK_IMAGE_ASPECT_DEPTH_BIT);
if (src_is_depth != dst_is_depth)
{
// TODO: Implement proper copy_typeless for vulkan that crosses the depth<->color aspect barrier
null_transfer_impl();
return;
}
if (src_bpp != dst_bpp || src_is_depth || dst_is_depth)
{

View file

@ -542,34 +542,40 @@ namespace vk
if (xfer_info.src_is_typeless)
{
auto internal_width = src->width() * xfer_info.src_scaling_hint;
auto format = xfer_info.src_native_format_override ?
const auto internal_width = src->width() * xfer_info.src_scaling_hint;
const auto format = xfer_info.src_native_format_override ?
VkFormat(xfer_info.src_native_format_override) :
vk::get_compatible_sampler_format(vk::get_current_renderer()->get_formats_support(), xfer_info.src_gcm_format);
const auto aspect = vk::get_aspect_flags(format);
// Transfer bits from src to typeless src
real_src = vk::get_typeless_helper(format, (u32)internal_width, src->height());
src_area.x1 = (u16)(src_area.x1 * xfer_info.src_scaling_hint);
src_area.x2 = (u16)(src_area.x2 * xfer_info.src_scaling_hint);
vk::change_image_layout(cmd, real_src, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { aspect, 0, 1, 0, 1 });
vk::copy_image_typeless(cmd, src, real_src, { 0, 0, (s32)src->width(), (s32)src->height() }, { 0, 0, (s32)internal_width, (s32)src->height() }, 1,
vk::get_aspect_flags(src->info.format), vk::get_aspect_flags(format));
vk::get_aspect_flags(src->info.format), aspect);
src_area.x1 = (u16)(src_area.x1 * xfer_info.src_scaling_hint);
src_area.x2 = (u16)(src_area.x2 * xfer_info.src_scaling_hint);
}
if (xfer_info.dst_is_typeless)
{
auto internal_width = dst->width() * xfer_info.dst_scaling_hint;
auto format = xfer_info.dst_native_format_override ?
const auto internal_width = dst->width() * xfer_info.dst_scaling_hint;
const auto format = xfer_info.dst_native_format_override ?
VkFormat(xfer_info.dst_native_format_override) :
vk::get_compatible_sampler_format(vk::get_current_renderer()->get_formats_support(), xfer_info.dst_gcm_format);
const auto aspect = vk::get_aspect_flags(format);
// Transfer bits from dst to typeless dst
real_dst = vk::get_typeless_helper(format, (u32)internal_width, dst->height());
dst_area.x1 = (u16)(dst_area.x1 * xfer_info.dst_scaling_hint);
dst_area.x2 = (u16)(dst_area.x2 * xfer_info.dst_scaling_hint);
vk::change_image_layout(cmd, real_dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { aspect, 0, 1, 0, 1 });
vk::copy_image_typeless(cmd, dst, real_dst, { 0, 0, (s32)dst->width(), (s32)dst->height() }, { 0, 0, (s32)internal_width, (s32)dst->height() }, 1,
vk::get_aspect_flags(dst->info.format), vk::get_aspect_flags(format));
vk::get_aspect_flags(dst->info.format), aspect);
dst_area.x1 = (u16)(dst_area.x1 * xfer_info.dst_scaling_hint);
dst_area.x2 = (u16)(dst_area.x2 * xfer_info.dst_scaling_hint);
}
else if (xfer_info.dst_context == rsx::texture_upload_context::framebuffer_storage)
{
@ -647,7 +653,5 @@ namespace vk
vk::copy_image_typeless(cmd, real_dst, dst, { 0, 0, (s32)internal_width, (s32)dst->height() }, { 0, 0, (s32)dst->width(), (s32)dst->height() }, 1,
vk::get_aspect_flags(real_dst->info.format), vk::get_aspect_flags(dst->info.format));
}
change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, { (VkImageAspectFlags)dst_aspect, 0, dst->info.mipLevels, 0, dst->info.arrayLayers });
}
}