@ -51,6 +51,10 @@ using VideoCore::Surface::IsPixelFormatInteger;
using VideoCore : : Surface : : SurfaceType ;
namespace {
[[nodiscard]] u32 GetMaxMipLevel ( u32 w , u32 h , u32 d ) {
return Common : : Log2Floor32 ( ( std : : max ) ( ( std : : max ) ( w , h ) , d ) ) + 1 ;
}
constexpr VkBorderColor ConvertBorderColor ( const std : : array < float , 4 > & color ) {
if ( color = = std : : array < float , 4 > { 0 , 0 , 0 , 0 } ) {
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK ;
@ -143,7 +147,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
. height = info . size . height > > samples_y ,
. depth = info . size . depth ,
} ;
auto const max_mipmap_levels = Common : : Log2Floor32 ( std : : max ( std : : max ( extent . width , extent . height ) , extent . depth ) ) + 1 ;
auto const max_mipmap_levels = GetMaxMipLevel ( extent . width , extent . height , extent . depth ) ;
auto mipmap_levels = u32 ( info . resources . levels ) ;
if ( mipmap_levels > max_mipmap_levels ) {
LOG_WARNING ( HW_GPU , " texture with too many mipmaps? {}, {} " , mipmap_levels , max_mipmap_levels ) ;
@ -156,7 +160,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
. imageType = ConvertImageType ( info . type ) ,
. format = format_info . format ,
. extent = extent ,
. mipLevels = u32 ( info . resources . levels ) ,
. mipLevels = mipmap_levels ,
. arrayLayers = u32 ( info . resources . layers ) ,
. samples = ConvertSampleCount ( info . num_samples ) ,
. tiling = VK_IMAGE_TILING_OPTIMAL ,
@ -354,13 +358,12 @@ void SanitizeDepthStencilSwizzle(std::array<SwizzleSource, 4>& swizzle,
return VK_IMAGE_VIEW_TYPE_2D ;
}
[[nodiscard]] VkImageSubresourceLayers MakeImageSubresourceLayers (
VideoCommon : : SubresourceLayers subresource , VkImageAspectFlags aspect_mask ) {
[[nodiscard]] VkImageSubresourceLayers MakeImageSubresourceLayers ( VideoCommon : : SubresourceLayers subresource , VkImageAspectFlags aspect_mask , u32 max_miplevel ) {
return VkImageSubresourceLayers {
. aspectMask = aspect_mask ,
. mipLevel = static_cast < u32 > ( subresource . base_level ) ,
. baseArrayLayer = static_cast < u32 > ( subresource . base_layer ) ,
. layerCount = static_cast < u32 > ( subresource . num_layers ) ,
. mipLevel = ( std : : min ) ( max_miplevel , u32 ( subresource . base_level ) ) ,
. baseArrayLayer = u32 ( subresource . base_layer ) ,
. layerCount = u32 ( subresource . num_layers ) ,
} ;
}
@ -374,31 +377,28 @@ void SanitizeDepthStencilSwizzle(std::array<SwizzleSource, 4>& swizzle,
[[nodiscard]] VkExtent3D MakeExtent3D ( VideoCommon : : Extent3D extent3d ) {
return VkExtent3D {
. width = static_cast < u32 > ( extent3d . width ) ,
. height = static_cast < u32 > ( extent3d . height ) ,
. depth = static_cast < u32 > ( extent3d . depth ) ,
. width = u32 ( extent3d . width ) ,
. height = u32 ( extent3d . height ) ,
. depth = u32 ( extent3d . depth ) ,
} ;
}
[[nodiscard]] VkImageCopy MakeImageCopy ( const VideoCommon : : ImageCopy & copy ,
VkImageAspectFlags aspect_mask ) noexcept {
[[nodiscard]] VkImageCopy MakeImageCopy ( const VideoCommon : : ImageCopy & copy , VkImageAspectFlags aspect_mask ) noexcept {
return VkImageCopy {
. srcSubresource = MakeImageSubresourceLayers ( copy . src_subresource , aspect_mask ) ,
. srcSubresource = MakeImageSubresourceLayers ( copy . src_subresource , aspect_mask , GetMaxMipLevel ( copy . extent . width , copy . extent . height , copy . extent . depth ) ) ,
. srcOffset = MakeOffset3D ( copy . src_offset ) ,
. dstSubresource = MakeImageSubresourceLayers ( copy . dst_subresource , aspect_mask ) ,
. dstSubresource = MakeImageSubresourceLayers ( copy . dst_subresource , aspect_mask , GetMaxMipLevel ( copy . extent . width , copy . extent . height , copy . extent . depth ) ) ,
. dstOffset = MakeOffset3D ( copy . dst_offset ) ,
. extent = MakeExtent3D ( copy . extent ) ,
} ;
}
[[nodiscard]] VkBufferImageCopy MakeBufferImageCopy ( const VideoCommon : : ImageCopy & copy , bool is_src ,
VkImageAspectFlags aspect_mask ) noexcept {
[[nodiscard]] VkBufferImageCopy MakeBufferImageCopy ( const VideoCommon : : ImageCopy & copy , bool is_src , VkImageAspectFlags aspect_mask ) noexcept {
return VkBufferImageCopy {
. bufferOffset = 0 ,
. bufferRowLength = 0 ,
. bufferImageHeight = 0 ,
. imageSubresource = MakeImageSubresourceLayers (
is_src ? copy . src_subresource : copy . dst_subresource , aspect_mask ) ,
. imageSubresource = MakeImageSubresourceLayers ( is_src ? copy . src_subresource : copy . dst_subresource , aspect_mask , GetMaxMipLevel ( copy . extent . width , copy . extent . height , copy . extent . depth ) ) ,
. imageOffset = MakeOffset3D ( is_src ? copy . src_offset : copy . dst_offset ) ,
. imageExtent = MakeExtent3D ( copy . extent ) ,
} ;
@ -410,9 +410,9 @@ TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t bu
std : : ranges : : transform (
copies , result . begin ( ) , [ buffer_offset ] ( const VideoCommon : : BufferCopy & copy ) {
return VkBufferCopy {
. srcOffset = static_cast < VkDeviceSize > ( copy . src_offset + buffer_offset ) ,
. dstOffset = static_cast < VkDeviceSize > ( copy . dst_offset ) ,
. size = static_cast < VkDeviceSize > ( copy . size ) ,
. srcOffset = VkDeviceSize ( copy . src_offset + buffer_offset ) ,
. dstOffset = VkDeviceSize ( copy . dst_offset ) ,
. size = VkDeviceSize ( copy . size ) ,
} ;
} ) ;
return result ;
@ -426,25 +426,22 @@ TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t bu
. bufferOffset = copy . buffer_offset + buffer_offset ,
. bufferRowLength = copy . buffer_row_length ,
. bufferImageHeight = copy . buffer_image_height ,
. imageSubresource =
{
. aspectMask = aspect_mask ,
. mipLevel = static_cast < u32 > ( copy . image_subresource . base_level ) ,
. baseArrayLayer = static_cast < u32 > ( copy . image_subresource . base_layer ) ,
. layerCount = static_cast < u32 > ( copy . image_subresource . num_layers ) ,
} ,
. imageOffset =
{
. x = copy . image_offset . x ,
. y = copy . image_offset . y ,
. z = copy . image_offset . z ,
} ,
. imageExtent =
{
. width = copy . image_extent . width ,
. height = copy . image_extent . height ,
. depth = copy . image_extent . depth ,
} ,
. imageSubresource = {
. aspectMask = aspect_mask ,
. mipLevel = ( std : : min ) ( u32 ( copy . image_subresource . base_level ) , GetMaxMipLevel ( copy . image_extent . width , copy . image_extent . height , copy . image_extent . depth ) ) ,
. baseArrayLayer = u32 ( copy . image_subresource . base_layer ) ,
. layerCount = u32 ( copy . image_subresource . num_layers ) ,
} ,
. imageOffset = {
. x = copy . image_offset . x ,
. y = copy . image_offset . y ,
. z = copy . image_offset . z ,
} ,
. imageExtent = {
. width = copy . image_extent . width ,
. height = copy . image_extent . height ,
. depth = copy . image_extent . depth ,
} ,
} ;
}
size_t buffer_offset ;
@ -464,14 +461,13 @@ TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t bu
}
}
[[nodiscard]] VkImageSubresourceRange MakeSubresourceRange ( VkImageAspectFlags aspect_mask ,
const SubresourceRange & range ) {
[[nodiscard]] VkImageSubresourceRange MakeSubresourceRange ( VkImageAspectFlags aspect_mask , const SubresourceRange & range ) {
return VkImageSubresourceRange {
. aspectMask = aspect_mask ,
. baseMipLevel = static_cast < u32 > ( range . base . level ) ,
. levelCount = static_cast < u32 > ( range . extent . levels ) ,
. baseArrayLayer = static_cast < u32 > ( range . base . layer ) ,
. layerCount = static_cast < u32 > ( range . extent . layers ) ,
. baseMipLevel = u32 ( range . base . level ) ,
. levelCount = u32 ( range . extent . levels ) ,
. baseArrayLayer = u32 ( range . base . layer ) ,
. layerCount = u32 ( range . extent . layers ) ,
} ;
}
@ -483,15 +479,16 @@ TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t bu
range . base . layer = 0 ;
range . extent . layers = 1 ;
}
range . extent . levels = ( std : : min ) ( range . extent . levels , s32 ( GetMaxMipLevel ( image_view - > size . width , image_view - > size . height , image_view - > size . depth ) ) ) ;
return MakeSubresourceRange ( ImageAspectMask ( image_view - > format ) , range ) ;
}
[[nodiscard]] VkImageSubresourceLayers MakeSubresourceLayers ( const ImageView * image_view ) {
return VkImageSubresourceLayers {
. aspectMask = ImageAspectMask ( image_view - > format ) ,
. mipLevel = static_cast < u32 > ( image_view - > range . base . level ) ,
. baseArrayLayer = static_cast < u32 > ( image_view - > range . base . layer ) ,
. layerCount = static_cast < u32 > ( image_view - > range . extent . layers ) ,
. mipLevel = ( std : : min ) ( u32 ( image_view - > range . base . level ) , GetMaxMipLevel ( image_view - > size . width , image_view - > size . height , image_view - > size . depth ) ) ,
. baseArrayLayer = u32 ( image_view - > range . base . layer ) ,
. layerCount = u32 ( image_view - > range . extent . layers ) ,
} ;
}
@ -546,11 +543,14 @@ struct RangedBarrierRange {
u32 min_layer = ( std : : numeric_limits < u32 > : : max ) ( ) ;
u32 max_layer = ( std : : numeric_limits < u32 > : : min ) ( ) ;
void AddLayers ( const VkImageSubresourceLayers & layers ) {
void AddLayers ( const VkImageSubresourceLayers & layers , u32 max_miplevel ) {
min_mip = ( std : : min ) ( min_mip , layers . mipLevel ) ;
max_mip = ( std : : max ) ( max_mip , layers . mipLevel + 1 ) ;
min_layer = ( std : : min ) ( min_layer , layers . baseArrayLayer ) ;
max_layer = ( std : : max ) ( max_layer , layers . baseArrayLayer + layers . layerCount ) ;
// clamp to proper so we dont access too many layers :)
min_mip = ( std : : min ) ( min_mip , max_miplevel ) ;
max_mip = ( std : : min ) ( max_mip , max_miplevel ) ;
}
VkImageSubresourceRange SubresourceRange ( VkImageAspectFlags aspect_mask ) const noexcept {
@ -563,47 +563,45 @@ struct RangedBarrierRange {
} ;
}
} ;
void CopyBufferToImage ( vk : : CommandBuffer cmdbuf , VkBuffer src_buffer , VkImage image ,
VkImageAspectFlags aspect_mask , bool is_initialized ,
std : : span < const VkBufferImageCopy > copies ) {
static constexpr VkAccessFlags WRITE_ACCESS_FLAGS =
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ;
static constexpr VkAccessFlags READ_ACCESS_FLAGS = VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT ;
void CopyBufferToImage ( vk : : CommandBuffer cmdbuf , VkBuffer src_buffer , VkImage image , VkImageAspectFlags aspect_mask , bool is_initialized , std : : span < const VkBufferImageCopy > copies ) {
static constexpr VkAccessFlags WRITE_ACCESS_FLAGS = VK_ACCESS_SHADER_WRITE_BIT
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ;
static constexpr VkAccessFlags READ_ACCESS_FLAGS = VK_ACCESS_SHADER_READ_BIT
| VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT ;
// Compute exact mip/layer range being written to
RangedBarrierRange range ;
for ( const auto & region : copies ) {
range . AddLayers ( region . imageSubresource ) ;
for ( const auto & copy : copies ) {
range . AddLayers ( copy . imageSubresource , GetMaxMipLevel ( copy . imageExtent . width , copy . imageExtent . height , copy . imageExtent . depth ) ) ;
}
const VkImageSubresourceRange subresource_range = range . SubresourceRange ( aspect_mask ) ;
const VkImageMemoryBarrier read_barrier {
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = WRITE_ACCESS_FLAGS ,
. dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED ,
. newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange = subresource_range ,
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = WRITE_ACCESS_FLAGS ,
. dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED ,
. newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange = subresource_range ,
} ;
const VkImageMemoryBarrier write_barrier {
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS ,
. oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. newLayout = VK_IMAGE_LAYOUT_GENERAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange = subresource_range ,
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS ,
. oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
. newLayout = VK_IMAGE_LAYOUT_GENERAL ,
. srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
. image = image ,
. subresourceRange = subresource_range ,
} ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
@ -750,59 +748,51 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
const VkFilter vk_filter = is_bilinear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST ;
scheduler . RequestOutsideRenderPassOperationContext ( ) ;
scheduler . Record ( [ dst_image , src_image , extent , resources , aspect_mask , resolution , is_2d ,
vk_filter , up_scaling ] ( vk : : CommandBuffer cmdbuf ) {
scheduler . Record ( [ depth = info . size . depth , dst_image , src_image , extent , resources , aspect_mask , resolution , is_2d , vk_filter , up_scaling ] ( vk : : CommandBuffer cmdbuf ) {
const VkOffset2D src_size {
. x = static_cast < s32 > ( up_scaling ? extent . width : resolution . ScaleUp ( extent . width ) ) ,
. y = static_cast < s32 > ( is_2d & & up_scaling ? extent . height
: resolution . ScaleUp ( extent . height ) ) ,
. x = s32 ( up_scaling ? extent . width : resolution . ScaleUp ( extent . width ) ) ,
. y = s32 ( is_2d & & up_scaling ? extent . height : resolution . ScaleUp ( extent . height ) ) ,
} ;
const VkOffset2D dst_size {
. x = static_cast < s32 > ( up_scaling ? resolution . ScaleUp ( extent . width ) : extent . width ) ,
. y = static_cast < s32 > ( is_2d & & up_scaling ? resolution . ScaleUp ( extent . height )
: extent . height ) ,
. x = s32 ( up_scaling ? resolution . ScaleUp ( extent . width ) : extent . width ) ,
. y = s32 ( is_2d & & up_scaling ? resolution . ScaleUp ( extent . height ) : extent . height ) ,
} ;
boost : : container : : small_vector < VkImageBlit , 4 > regions ;
regions . reserve ( resources . levels ) ;
for ( s32 level = 0 ; level < resources . levels ; level + + ) {
regions . push_back ( {
u32 const src_levels = ( std : : min ) ( resources . levels , s32 ( GetMaxMipLevel ( src_size . x , src_size . y , depth ) ) ) ;
u32 const dst_levels = ( std : : min ) ( resources . levels , s32 ( GetMaxMipLevel ( dst_size . x , dst_size . y , depth ) ) ) ;
u32 const max_levels = ( std : : max ) ( src_levels , dst_levels ) ;
std : : array < VkImageBlit , 16 > regions ;
ASSERT ( regions . size ( ) > = max_levels ) ;
for ( u32 i = 0 ; i < max_levels ; + + i ) {
regions [ i ] = VkImageBlit {
. srcSubresource {
. aspectMask = aspect_mask ,
. mipLevel = static_cast < u32 > ( level ) ,
. mipLevel = ( std : : min ) ( i , src_levels ) ,
. baseArrayLayer = 0 ,
. layerCount = static_cast < u32 > ( resources . layers ) ,
. layerCount = u32 ( resources . layers ) ,
} ,
. srcOffsets {
{ . x = 0 , . y = 0 , . z = 0 , } ,
{
. x = 0 ,
. y = 0 ,
. z = 0 ,
} ,
{
. x = ( std : : max ) ( 1 , src_size . x > > level ) ,
. y = ( std : : max ) ( 1 , src_size . y > > level ) ,
. x = ( std : : max ) ( 1 , src_size . x > > s32 ( i ) ) ,
. y = ( std : : max ) ( 1 , src_size . y > > s32 ( i ) ) ,
. z = 1 ,
} ,
} ,
. dstSubresource {
. aspectMask = aspect_mask ,
. mipLevel = static_cast < u32 > ( level ) ,
. mipLevel = ( std : : min ) ( i , dst_levels ) ,
. baseArrayLayer = 0 ,
. layerCount = static_cast < u32 > ( resources . layers ) ,
. layerCount = u32 ( resources . layers ) ,
} ,
. dstOffsets {
{ . x = 0 , . y = 0 , . z = 0 , } ,
{
. x = 0 ,
. y = 0 ,
. z = 0 ,
} ,
{
. x = ( std : : max ) ( 1 , dst_size . x > > level ) ,
. y = ( std : : max ) ( 1 , dst_size . y > > level ) ,
. x = ( std : : max ) ( 1 , dst_size . x > > s32 ( i ) ) ,
. y = ( std : : max ) ( 1 , dst_size . y > > s32 ( i ) ) ,
. z = 1 ,
} ,
} ,
} ) ;
} ;
}
const VkImageSubresourceRange subresource_range {
. aspectMask = aspect_mask ,
@ -827,9 +817,9 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
VkImageMemoryBarrier {
. sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
. pNext = nullptr ,
. srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT ,
. srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
| VK_ACCESS_TRANSFER_WRITE_BIT ,
. dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ,
. oldLayout = VK_IMAGE_LAYOUT_UNDEFINED , // Discard contents
. newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ,
@ -865,12 +855,9 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
. subresourceRange = subresource_range ,
} ,
} ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_ALL_COMMANDS_BIT , VK_PIPELINE_STAGE_TRANSFER_BIT ,
0 , nullptr , nullptr , read_barriers ) ;
cmdbuf . BlitImage ( src_image , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL , dst_image ,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL , regions , vk_filter ) ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_TRANSFER_BIT , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT ,
0 , nullptr , nullptr , write_barriers ) ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_ALL_COMMANDS_BIT , VK_PIPELINE_STAGE_TRANSFER_BIT , 0 , nullptr , nullptr , read_barriers ) ;
cmdbuf . BlitImage ( src_image , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL , dst_image , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL , vk : : Span ( regions . data ( ) , max_levels ) , vk_filter ) ;
cmdbuf . PipelineBarrier ( VK_PIPELINE_STAGE_TRANSFER_BIT , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT , 0 , nullptr , nullptr , write_barriers ) ;
} ) ;
}
} // Anonymous namespace
@ -1046,10 +1033,10 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
RangedBarrierRange dst_range ;
RangedBarrierRange src_range ;
for ( const VkBufferImageCopy & copy : vk_in_copies ) {
src_range . AddLayers ( copy . imageSubresource ) ;
src_range . AddLayers ( copy . imageSubresource , GetMaxMipLevel ( copy . imageExtent . width , copy . imageExtent . height , copy . imageExtent . depth ) ) ;
}
for ( const VkBufferImageCopy & copy : vk_out_copies ) {
dst_range . AddLayers ( copy . imageSubresource ) ;
dst_range . AddLayers ( copy . imageSubresource , GetMaxMipLevel ( copy . imageExtent . width , copy . imageExtent . height , copy . imageExtent . depth ) ) ;
}
static constexpr VkMemoryBarrier READ_BARRIER {
. sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER ,
@ -1482,11 +1469,10 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
const VkImage src_image = src . Handle ( ) ;
scheduler . RequestOutsideRenderPassOperationContext ( ) ;
scheduler . Record ( [ dst_image , src_image , aspect_mask , vk_copies ] ( vk : : CommandBuffer cmdbuf ) {
RangedBarrierRange dst_range ;
RangedBarrierRange src_range ;
RangedBarrierRange dst_range , src_range ;
for ( const VkImageCopy & copy : vk_copies ) {
dst_range . AddLayers ( copy . dstSubresource ) ;
src_range . AddLayers ( copy . srcSubresource ) ;
dst_range . AddLayers ( copy . dstSubresource , GetMaxMipLevel ( copy . extent . width , copy . extent . height , copy . extent . depth ) ) ;
src_range . AddLayers ( copy . srcSubresource , GetMaxMipLevel ( copy . extent . width , copy . extent . height , copy . extent . depth ) ) ;
}
const std : : array pre_barriers {
VkImageMemoryBarrier {
@ -1726,8 +1712,7 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
const VkImage temp_vk_image = * temp_wrapper - > original_image ;
const VkImageAspectFlags vk_aspect_mask = temp_wrapper - > aspect_mask ;
scheduler - > Record ( [ src_buffer , temp_vk_image , vk_aspect_mask , vk_copies ,
keep = temp_wrapper ] ( vk : : CommandBuffer cmdbuf ) {
scheduler - > Record ( [ src_buffer , temp_vk_image , vk_aspect_mask , vk_copies , keep = temp_wrapper ] ( vk : : CommandBuffer cmdbuf ) {
CopyBufferToImage ( cmdbuf , src_buffer , temp_vk_image , vk_aspect_mask , false , VideoCommon : : FixSmallVectorADL ( vk_copies ) ) ;
} ) ;
@ -2123,11 +2108,11 @@ bool Image::NeedsScaleHelper() const {
return needs_blit_helper ;
}
ImageView : : ImageView ( TextureCacheRuntime & runtime , const VideoCommon : : ImageViewInfo & info ,
ImageId image_id_ , Image & image )
: VideoCommon : : ImageViewBase { info , image . info , image_id_ , image . gpu_addr } ,
device { & runtime . device } , image_handle { image . Handle ( ) } ,
samples ( ConvertSampleCount ( image . info . num_samples ) ) {
ImageView : : ImageView ( TextureCacheRuntime & runtime , const VideoCommon : : ImageViewInfo & info , ImageId image_id_ , Image & image )
: VideoCommon : : ImageViewBase { info , image . info , image_id_ , image . gpu_addr }
, device { & runtime . device } , image_handle { image . Handle ( ) }
, samples ( ConvertSampleCount ( image . info . num_samples ) )
{
using Shader : : TextureType ;
const VkImageAspectFlags aspect_mask = ImageViewAspectMask ( info ) ;
@ -2139,9 +2124,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
} ;
if ( ! info . IsRenderTarget ( ) ) {
swizzle = info . Swizzle ( ) ;
TryTransformSwizzleIfNeeded ( format , swizzle ,
device - > MustEmulateBGR565 ( ) ,
! device - > IsExt4444FormatsSupported ( ) ) ;
TryTransformSwizzleIfNeeded ( format , swizzle , device - > MustEmulateBGR565 ( ) , ! device - > IsExt4444FormatsSupported ( ) ) ;
if ( ( aspect_mask & ( VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT ) ) ! = 0 ) {
std : : ranges : : transform ( swizzle , swizzle . begin ( ) , ConvertGreenRed ) ;
SanitizeDepthStencilSwizzle ( swizzle , device - > SupportsDepthStencilSwizzleOne ( ) ) ;
@ -2156,6 +2139,8 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
. pNext = nullptr ,
. usage = clamped_view_usage ,
} ;
SubresourceRange range = info . range ;
range . extent . levels = ( std : : min ) ( range . extent . levels , s32 ( GetMaxMipLevel ( image . info . size . width , image . info . size . height , image . info . size . depth ) ) ) ;
const VkImageViewCreateInfo create_info {
. sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO ,
. pNext = & image_view_usage ,
@ -2169,7 +2154,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
. b = ComponentSwizzle ( swizzle [ 2 ] ) ,
. a = ComponentSwizzle ( swizzle [ 3 ] ) ,
} ,
. subresourceRange = MakeSubresourceRange ( aspect_mask , info . range ) ,
. subresourceRange = MakeSubresourceRange ( aspect_mask , range ) ,
} ;
const auto create = [ & ] ( TextureType tex_type , std : : optional < u32 > num_layers ) {
VkImageViewCreateInfo ci { create_info } ;
@ -2301,6 +2286,8 @@ bool ImageView::IsRescaled() const noexcept {
}
vk : : ImageView ImageView : : MakeView ( VkFormat vk_format , VkImageAspectFlags aspect_mask ) {
auto subresource_range = MakeSubresourceRange ( aspect_mask , range ) ;
subresource_range . levelCount = ( std : : min ) ( subresource_range . levelCount , GetMaxMipLevel ( size . width , size . height , size . depth ) ) ;
return device - > GetLogical ( ) . CreateImageView ( {
. sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO ,
. pNext = nullptr ,
@ -2314,7 +2301,7 @@ vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_
. b = VK_COMPONENT_SWIZZLE_IDENTITY ,
. a = VK_COMPONENT_SWIZZLE_IDENTITY ,
} ,
. subresourceRange = MakeSubresourceRange ( aspect_mask , range ) ,
. subresourceRange = subresource_range ,
} ) ;
}
@ -2369,7 +2356,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
. mipLodBias = tsc . LodBias ( ) ,
. anisotropyEnable = static_cast < VkBool32 > ( anisotropy > 1.0f ? VK_TRUE : VK_FALSE ) ,
. maxAnisotropy = anisotropy ,
. compareEnable = tsc . depth_compare_enabled ,
. compareEnable = false , //tsc.depth_compare_enabled,
. compareOp = MaxwellToVK : : Sampler : : DepthCompareFunction ( tsc . depth_compare_func ) ,
. minLod = tsc . mipmap_filter = = TextureMipmapFilter : : None ? 0.0f : tsc . MinLod ( ) ,
. maxLod = tsc . mipmap_filter = = TextureMipmapFilter : : None ? 0.25f : tsc . MaxLod ( ) ,