rsx: Unify composite texture creation and management

- Some texture accesses require image compositing steps to assemble the requested image from existing subresources.
  Handle all the common routines in a unified manner to avoid having one broken path (e.g mipmap gather not supporting bitcast operations)
This commit is contained in:
kd-11 2020-08-09 16:28:13 +03:00 committed by kd-11
commit 6850533b50
2 changed files with 102 additions and 186 deletions

View file

@ -515,14 +515,14 @@ namespace gl
} }
gl::texture_view* create_temporary_subresource_impl(gl::command_context& cmd, gl::texture* src, GLenum sized_internal_fmt, GLenum dst_type, u32 gcm_format, gl::texture_view* create_temporary_subresource_impl(gl::command_context& cmd, gl::texture* src, GLenum sized_internal_fmt, GLenum dst_type, u32 gcm_format,
u16 x, u16 y, u16 width, u16 height, const rsx::texture_channel_remap_t& remap, bool copy) u16 x, u16 y, u16 width, u16 height, u16 depth, u8 mipmaps, const rsx::texture_channel_remap_t& remap, bool copy)
{ {
if (sized_internal_fmt == GL_NONE) if (sized_internal_fmt == GL_NONE)
{ {
sized_internal_fmt = gl::get_sized_internal_format(gcm_format); sized_internal_fmt = gl::get_sized_internal_format(gcm_format);
} }
std::unique_ptr<gl::texture> dst = std::make_unique<gl::viewable_image>(dst_type, width, height, 1, 1, sized_internal_fmt); std::unique_ptr<gl::texture> dst = std::make_unique<gl::viewable_image>(dst_type, width, height, depth, mipmaps, sized_internal_fmt);
if (copy) if (copy)
{ {
@ -736,57 +736,31 @@ namespace gl
gl::texture_view* create_temporary_subresource_view(gl::command_context &cmd, gl::texture** src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, gl::texture_view* create_temporary_subresource_view(gl::command_context &cmd, gl::texture** src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h,
const rsx::texture_channel_remap_t& remap_vector) override const rsx::texture_channel_remap_t& remap_vector) override
{ {
return create_temporary_subresource_impl(cmd, *src, GL_NONE, GL_TEXTURE_2D, gcm_format, x, y, w, h, remap_vector, true); return create_temporary_subresource_impl(cmd, *src, GL_NONE, GL_TEXTURE_2D, gcm_format, x, y, w, h, 1, 1, remap_vector, true);
} }
gl::texture_view* create_temporary_subresource_view(gl::command_context &cmd, gl::texture* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, gl::texture_view* create_temporary_subresource_view(gl::command_context &cmd, gl::texture* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h,
const rsx::texture_channel_remap_t& remap_vector) override const rsx::texture_channel_remap_t& remap_vector) override
{ {
return create_temporary_subresource_impl(cmd, src, static_cast<GLenum>(src->get_internal_format()), return create_temporary_subresource_impl(cmd, src, static_cast<GLenum>(src->get_internal_format()),
GL_TEXTURE_2D, gcm_format, x, y, w, h, remap_vector, true); GL_TEXTURE_2D, gcm_format, x, y, w, h, 1, 1, remap_vector, true);
} }
gl::texture_view* generate_cubemap_from_images(gl::command_context& cmd, u32 gcm_format, u16 size, const std::vector<copy_region_descriptor>& sources, const rsx::texture_channel_remap_t& /*remap_vector*/) override gl::texture_view* generate_cubemap_from_images(gl::command_context& cmd, u32 gcm_format, u16 size, const std::vector<copy_region_descriptor>& sources, const rsx::texture_channel_remap_t& remap_vector) override
{ {
const GLenum ifmt = gl::get_sized_internal_format(gcm_format); auto _template = get_template_from_collection_impl(sources);
std::unique_ptr<gl::texture> dst_image = std::make_unique<gl::viewable_image>(GL_TEXTURE_CUBE_MAP, size, size, 1, 1, ifmt); auto result = create_temporary_subresource_impl(cmd, _template, GL_NONE, GL_TEXTURE_3D, gcm_format, 0, 0, size, size, 1, 1, remap_vector, false);
auto view = std::make_unique<gl::texture_view>(dst_image.get(), GL_TEXTURE_CUBE_MAP, ifmt);
//Empty GL_ERROR copy_transfer_regions_impl(cmd, result->image(), sources);
glGetError();
copy_transfer_regions_impl(cmd, dst_image.get(), sources);
if (GLenum err = glGetError())
{
rsx_log.warning("Failed to copy image subresource with GL error 0x%X", err);
return nullptr;
}
auto result = view.get();
m_temporary_surfaces.emplace_back(dst_image, view);
return result; return result;
} }
gl::texture_view* generate_3d_from_2d_images(gl::command_context& cmd, u32 gcm_format, u16 width, u16 height, u16 depth, const std::vector<copy_region_descriptor>& sources, const rsx::texture_channel_remap_t& /*remap_vector*/) override gl::texture_view* generate_3d_from_2d_images(gl::command_context& cmd, u32 gcm_format, u16 width, u16 height, u16 depth, const std::vector<copy_region_descriptor>& sources, const rsx::texture_channel_remap_t& remap_vector) override
{ {
const GLenum ifmt = gl::get_sized_internal_format(gcm_format); auto _template = get_template_from_collection_impl(sources);
std::unique_ptr<gl::texture> dst_image = std::make_unique<gl::viewable_image>(GL_TEXTURE_3D, width, height, depth, 1, ifmt); auto result = create_temporary_subresource_impl(cmd, _template, GL_NONE, GL_TEXTURE_3D, gcm_format, 0, 0, width, height, depth, 1, remap_vector, false);
auto view = std::make_unique<gl::texture_view>(dst_image.get(), GL_TEXTURE_3D, ifmt);
//Empty GL_ERROR copy_transfer_regions_impl(cmd, result->image(), sources);
glGetError();
copy_transfer_regions_impl(cmd, dst_image.get(), sources);
if (GLenum err = glGetError())
{
rsx_log.warning("Failed to copy image subresource with GL error 0x%X", err);
return nullptr;
}
auto result = view.get();
m_temporary_surfaces.emplace_back(dst_image, view);
return result; return result;
} }
@ -794,30 +768,21 @@ namespace gl
const rsx::texture_channel_remap_t& remap_vector) override const rsx::texture_channel_remap_t& remap_vector) override
{ {
auto _template = get_template_from_collection_impl(sections_to_copy); auto _template = get_template_from_collection_impl(sections_to_copy);
auto result = create_temporary_subresource_impl(cmd, _template, GL_NONE, GL_TEXTURE_2D, gcm_format, 0, 0, width, height, remap_vector, false); auto result = create_temporary_subresource_impl(cmd, _template, GL_NONE, GL_TEXTURE_2D, gcm_format, 0, 0, width, height, 1, 1, remap_vector, false);
copy_transfer_regions_impl(cmd, result->image(), sections_to_copy); copy_transfer_regions_impl(cmd, result->image(), sections_to_copy);
return result; return result;
} }
gl::texture_view* generate_2d_mipmaps_from_images(gl::command_context& cmd, u32 /*gcm_format*/, u16 width, u16 height, const std::vector<copy_region_descriptor>& sections_to_copy, gl::texture_view* generate_2d_mipmaps_from_images(gl::command_context& cmd, u32 gcm_format, u16 width, u16 height, const std::vector<copy_region_descriptor>& sections_to_copy,
const rsx::texture_channel_remap_t& remap_vector) override const rsx::texture_channel_remap_t& remap_vector) override
{ {
const auto _template = sections_to_copy.front().src; const auto mipmaps = ::narrow<u8>(sections_to_copy.size());
const GLenum ifmt = static_cast<GLenum>(_template->get_internal_format()); auto _template = get_template_from_collection_impl(sections_to_copy);
const u8 mipmaps = ::narrow<u8>(sections_to_copy.size()); auto result = create_temporary_subresource_impl(cmd, _template, GL_NONE, GL_TEXTURE_2D, gcm_format, 0, 0, width, height, 1, mipmaps, remap_vector, false);
const auto swizzle = _template->get_native_component_layout();
auto image_ptr = new gl::viewable_image(GL_TEXTURE_2D, width, height, 1, mipmaps, ifmt); copy_transfer_regions_impl(cmd, result->image(), sections_to_copy);
image_ptr->set_native_component_layout(swizzle); return result;
copy_transfer_regions_impl(cmd, image_ptr, sections_to_copy);
auto view = image_ptr->get_view(get_remap_encoding(remap_vector), remap_vector);
std::unique_ptr<gl::texture> dst_image(image_ptr);
m_temporary_surfaces.emplace_back(dst_image);
return view;
} }
void release_temporary_subresource(gl::texture_view* view) override void release_temporary_subresource(gl::texture_view* view) override

View file

@ -866,20 +866,22 @@ namespace vk
protected: protected:
vk::image_view* create_temporary_subresource_view_impl(vk::command_buffer& cmd, vk::image* source, VkImageType image_type, VkImageViewType view_type, vk::image_view* create_temporary_subresource_view_impl(vk::command_buffer& cmd, vk::image* source, VkImageType image_type, VkImageViewType view_type,
u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const rsx::texture_channel_remap_t& remap_vector, bool copy) u32 gcm_format, u16 x, u16 y, u16 w, u16 h, u16 d, u8 mips, const rsx::texture_channel_remap_t& remap_vector, bool copy)
{ {
std::unique_ptr<vk::viewable_image> image; std::unique_ptr<vk::viewable_image> image;
VkImageCreateFlags image_flags = (view_type == VK_IMAGE_VIEW_TYPE_CUBE) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0; VkImageCreateFlags image_flags = (view_type == VK_IMAGE_VIEW_TYPE_CUBE) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
VkFormat dst_format = vk::get_compatible_sampler_format(m_formats_support, gcm_format); VkFormat dst_format = vk::get_compatible_sampler_format(m_formats_support, gcm_format);
u16 layers = 1;
if (!image_flags) [[likely]] if (!image_flags) [[likely]]
{ {
image = find_temporary_image(dst_format, w, h, 1, 1); image = find_temporary_image(dst_format, w, h, 1, mips);
} }
else else
{ {
image = find_temporary_cubemap(dst_format, w); image = find_temporary_cubemap(dst_format, w);
layers = 6;
} }
if (!image) if (!image)
@ -887,7 +889,7 @@ namespace vk
image = std::make_unique<vk::viewable_image>(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image = std::make_unique<vk::viewable_image>(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
image_type, image_type,
dst_format, dst_format,
w, h, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, w, h, d, mips, layers, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, image_flags); VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, image_flags);
} }
@ -938,7 +940,7 @@ namespace vk
u16 x, u16 y, u16 w, u16 h, const rsx::texture_channel_remap_t& remap_vector) override u16 x, u16 y, u16 w, u16 h, const rsx::texture_channel_remap_t& remap_vector) override
{ {
return create_temporary_subresource_view_impl(cmd, source, source->info.imageType, VK_IMAGE_VIEW_TYPE_2D, return create_temporary_subresource_view_impl(cmd, source, source->info.imageType, VK_IMAGE_VIEW_TYPE_2D,
gcm_format, x, y, w, h, remap_vector, true); gcm_format, x, y, w, h, 1, 1, remap_vector, true);
} }
vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image** source, u32 gcm_format, vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image** source, u32 gcm_format,
@ -948,115 +950,40 @@ namespace vk
} }
vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 size, vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 size,
const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& /*remap_vector*/) override
{
std::unique_ptr<vk::viewable_image> image;
VkFormat dst_format = vk::get_compatible_sampler_format(m_formats_support, gcm_format);
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(dst_format);
if (image = find_temporary_cubemap(dst_format, size); !image)
{
image = std::make_unique<vk::viewable_image>(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D,
dst_format,
size, size, 1, 1, 6, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT);
}
else if (auto src = sections_to_copy[0].src; src && src->format() == dst_format)
{
image->set_native_component_layout(src->native_component_map);
}
else
{
image->set_native_component_layout({ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A });
}
auto view = image->get_view(0xAAE4, rsx::default_remap_vector);
VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 6 };
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);
if (!(dst_aspect & VK_IMAGE_ASPECT_DEPTH_BIT))
{
VkClearColorValue clear = {};
vkCmdClearColorImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
else
{
VkClearDepthStencilValue clear = { 1.f, 0 };
vkCmdClearDepthStencilImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
copy_transfer_regions_impl(cmd, image.get(), sections_to_copy);
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range);
const u32 resource_memory = size * size * 6 * 4; //Rough approximate
m_temporary_storage.emplace_back(image);
m_temporary_storage.back().block_size = resource_memory;
m_temporary_memory_size += resource_memory;
return view;
}
vk::image_view* generate_3d_from_2d_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height, u16 depth,
const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& /*remap_vector*/) override
{
std::unique_ptr<vk::viewable_image> image;
VkFormat dst_format = vk::get_compatible_sampler_format(m_formats_support, gcm_format);
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(dst_format);
if (image = find_temporary_image(dst_format, width, height, depth, 1); !image)
{
image = std::make_unique<vk::viewable_image>(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_3D,
dst_format,
width, height, depth, 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);
}
else if (auto src = sections_to_copy[0].src; src && src->format() == dst_format)
{
image->set_native_component_layout(src->native_component_map);
}
else
{
image->set_native_component_layout({ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A });
}
auto view = image->get_view(0xAAE4, rsx::default_remap_vector);
VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 1 };
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);
if (!(dst_aspect & VK_IMAGE_ASPECT_DEPTH_BIT))
{
VkClearColorValue clear = {};
vkCmdClearColorImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
else
{
VkClearDepthStencilValue clear = { 1.f, 0 };
vkCmdClearDepthStencilImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
copy_transfer_regions_impl(cmd, image.get(), sections_to_copy);
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range);
const u32 resource_memory = width * height * depth * 4; //Rough approximate
m_temporary_storage.emplace_back(image);
m_temporary_storage.back().block_size = resource_memory;
m_temporary_memory_size += resource_memory;
return view;
}
vk::image_view* generate_atlas_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height,
const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& remap_vector) override const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& remap_vector) override
{ {
auto _template = get_template_from_collection_impl(sections_to_copy); auto _template = get_template_from_collection_impl(sections_to_copy);
auto result = create_temporary_subresource_view_impl(cmd, _template, VK_IMAGE_TYPE_2D, auto result = create_temporary_subresource_view_impl(cmd, _template, VK_IMAGE_TYPE_2D,
VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, remap_vector, false); VK_IMAGE_VIEW_TYPE_CUBE, gcm_format, 0, 0, size, size, 1, 1, remap_vector, false);
const auto image = result->image();
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(result->info.format);
VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 6 };
vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);
if (!(dst_aspect & VK_IMAGE_ASPECT_DEPTH_BIT))
{
VkClearColorValue clear = {};
vkCmdClearColorImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
else
{
VkClearDepthStencilValue clear = { 1.f, 0 };
vkCmdClearDepthStencilImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
copy_transfer_regions_impl(cmd, image, sections_to_copy);
vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range);
return result;
}
vk::image_view* generate_3d_from_2d_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height, u16 depth,
const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& remap_vector) override
{
auto _template = get_template_from_collection_impl(sections_to_copy);
auto result = create_temporary_subresource_view_impl(cmd, _template, VK_IMAGE_TYPE_3D,
VK_IMAGE_VIEW_TYPE_3D, gcm_format, 0, 0, width, height, depth, 1, remap_vector, false);
const auto image = result->image(); const auto image = result->image();
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(result->info.format); VkImageAspectFlags dst_aspect = vk::get_aspect_flags(result->info.format);
@ -1080,39 +1007,63 @@ namespace vk
return result; return result;
} }
vk::image_view* generate_2d_mipmaps_from_images(vk::command_buffer& cmd, u32 /*gcm_format*/, u16 width, u16 height, vk::image_view* generate_atlas_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height,
const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& remap_vector) override const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& remap_vector) override
{ {
const auto _template = sections_to_copy.front().src; auto _template = get_template_from_collection_impl(sections_to_copy);
const auto mipmaps = ::narrow<u8>(sections_to_copy.size()); auto result = create_temporary_subresource_view_impl(cmd, _template, VK_IMAGE_TYPE_2D,
VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, 1, 1, remap_vector, false);
std::unique_ptr<vk::viewable_image> image; const auto image = result->image();
if (image = find_temporary_image(_template->format(), width, height, 1, mipmaps); !image) VkImageAspectFlags dst_aspect = vk::get_aspect_flags(result->info.format);
VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 1 };
vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);
if (!(dst_aspect & VK_IMAGE_ASPECT_DEPTH_BIT))
{ {
image = std::make_unique<vk::viewable_image>(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VkClearColorValue clear = {};
_template->info.imageType, vkCmdClearColorImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
_template->info.format, }
width, height, 1, mipmaps, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, else
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0); {
VkClearDepthStencilValue clear = { 1.f, 0 };
image->set_native_component_layout(_template->native_component_map); vkCmdClearDepthStencilImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
} }
auto view = image->get_view(get_remap_encoding(remap_vector), remap_vector); copy_transfer_regions_impl(cmd, image, sections_to_copy);
VkImageSubresourceRange dst_range = { _template->aspect(), 0, mipmaps, 0, 1 }; vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range);
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range); return result;
}
copy_transfer_regions_impl(cmd, image.get(), sections_to_copy); vk::image_view* generate_2d_mipmaps_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height,
const std::vector<copy_region_descriptor>& sections_to_copy, const rsx::texture_channel_remap_t& remap_vector) override
{
const auto mipmaps = ::narrow<u8>(sections_to_copy.size());
auto _template = get_template_from_collection_impl(sections_to_copy);
auto result = create_temporary_subresource_view_impl(cmd, _template, VK_IMAGE_TYPE_2D,
VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, 1, mipmaps, remap_vector, false);
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range); const auto image = result->image();
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(result->info.format);
VkImageSubresourceRange dst_range = { dst_aspect, 0, mipmaps, 0, 1 };
vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);
const u32 resource_memory = width * height * 2 * 4; // Rough approximate if (!(dst_aspect & VK_IMAGE_ASPECT_DEPTH_BIT))
m_temporary_storage.emplace_back(image); {
m_temporary_storage.back().block_size = resource_memory; VkClearColorValue clear = {};
m_temporary_memory_size += resource_memory; vkCmdClearColorImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
else
{
VkClearDepthStencilValue clear = { 1.f, 0 };
vkCmdClearDepthStencilImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
return view; copy_transfer_regions_impl(cmd, image, sections_to_copy);
vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range);
return result;
} }
void release_temporary_subresource(vk::image_view* view) override void release_temporary_subresource(vk::image_view* view) override