diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 41 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.h | 3 | 
4 files changed, 48 insertions, 23 deletions
| diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 5ca67c413..fd334a146 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -63,7 +63,7 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in      const auto conv = [scale](float value) {          float new_value = value * scale;          if (scale < 1.0f) { -            bool sign = std::signbit(new_value); +            const bool sign = std::signbit(value);              new_value = std::round(std::abs(new_value));              new_value = sign ? -new_value : new_value;          } @@ -96,21 +96,22 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in  VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u32 down_shift = 0) {      const auto& src = regs.scissor_test[index];      VkRect2D scissor; -    const auto scale_up = [&](u32 value) -> u32 { +    const auto scale_up = [&](s32 value) -> s32 {          if (value == 0) {              return 0U;          } -        const u32 upset = value * up_scale; -        u32 acumm = 0; +        const s32 upset = value * up_scale; +        s32 acumm = 0;          if ((up_scale >> down_shift) == 0) { -            acumm = upset & 0x1; +            acumm = upset % 2;          } -        const u32 converted_value = (value * up_scale) >> down_shift; -        return std::max<u32>(converted_value + acumm, 1U); +        const s32 converted_value = (value * up_scale) >> down_shift; +        return value < 0 ? std::min<s32>(converted_value - acumm, -1) +                         : std::max<s32>(converted_value + acumm, 1);      };      if (src.enable) { -        scissor.offset.x = static_cast<s32>(scale_up(src.min_x)); -        scissor.offset.y = static_cast<s32>(scale_up(src.min_y)); +        scissor.offset.x = scale_up(static_cast<s32>(src.min_x)); +        scissor.offset.y = scale_up(static_cast<s32>(src.min_y));          scissor.extent.width = scale_up(src.max_x - src.min_x);          scissor.extent.height = scale_up(src.max_y - src.min_y);      } else { diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 13914dc8b..a32c11d04 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1037,8 +1037,11 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA          if (overlap.info.num_samples != new_image.info.num_samples) {              LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented");          } else { +            const auto& resolution = Settings::values.resolution_info;              const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value(); -            auto copies = MakeShrinkImageCopies(new_info, overlap.info, base); +            const u32 up_scale = can_rescale ? resolution.up_scale : 1; +            const u32 down_shift = can_rescale ? resolution.down_shift : 0; +            auto copies = MakeShrinkImageCopies(new_info, overlap.info, base, up_scale, down_shift);              runtime.CopyImage(new_image, overlap, std::move(copies));          }          if (True(overlap.flags & ImageFlagBits::Tracked)) { @@ -1659,19 +1662,35 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) {          const ImageBase& rhs_image = slot_images[rhs->id];          return lhs_image.modification_tick < rhs_image.modification_tick;      }); +    const auto& resolution = Settings::values.resolution_info;      for (const AliasedImage* const aliased : aliased_images) { -        if (any_rescaled) { -            Image& aliased_image = slot_images[aliased->id]; -            if (can_rescale) { -                ScaleUp(aliased_image); -            } else { -                ScaleDown(aliased_image); -                if (any_blacklisted) { -                    aliased_image.flags |= ImageFlagBits::Blacklisted; -                } +        if (!resolution.active | !any_rescaled) { +            CopyImage(image_id, aliased->id, aliased->copies); +            continue; +        } +        Image& aliased_image = slot_images[aliased->id]; +        if (!can_rescale) { +            ScaleDown(aliased_image); +            if (any_blacklisted) { +                aliased_image.flags |= ImageFlagBits::Blacklisted; +            } +            CopyImage(image_id, aliased->id, aliased->copies); +            continue; +        } +        ScaleUp(aliased_image); + +        const bool both_2d{image.info.type == ImageType::e2D && +                           aliased_image.info.type == ImageType::e2D}; +        auto copies = aliased->copies; +        for (auto copy : copies) { +            copy.extent.width = std::max<u32>( +                (copy.extent.width * resolution.up_scale) >> resolution.down_shift, 1); +            if (both_2d) { +                copy.extent.height = std::max<u32>( +                    (copy.extent.height * resolution.up_scale) >> resolution.down_shift, 1);              }          } -        CopyImage(image_id, aliased->id, aliased->copies); +        CopyImage(image_id, aliased->id, copies);      }  } diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 59cf2f561..9922aa0cc 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -723,7 +723,7 @@ ImageViewType RenderTargetImageViewType(const ImageInfo& info) noexcept {  }  std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageInfo& src, -                                             SubresourceBase base) { +                                             SubresourceBase base, u32 up_scale, u32 down_shift) {      ASSERT(dst.resources.levels >= src.resources.levels);      ASSERT(dst.num_samples == src.num_samples); @@ -732,7 +732,7 @@ std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageIn          ASSERT(src.type == ImageType::e3D);          ASSERT(src.resources.levels == 1);      } - +    const bool both_2d{src.type == ImageType::e2D && dst.type == ImageType::e2D};      std::vector<ImageCopy> copies;      copies.reserve(src.resources.levels);      for (s32 level = 0; level < src.resources.levels; ++level) { @@ -762,6 +762,10 @@ std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageIn          if (is_dst_3d) {              copy.extent.depth = src.size.depth;          } +        copy.extent.width = std::max<u32>((copy.extent.width * up_scale) >> down_shift, 1); +        if (both_2d) { +            copy.extent.height = std::max<u32>((copy.extent.height * up_scale) >> down_shift, 1); +        }      }      return copies;  } diff --git a/src/video_core/texture_cache/util.h b/src/video_core/texture_cache/util.h index 766502908..7af52de2e 100644 --- a/src/video_core/texture_cache/util.h +++ b/src/video_core/texture_cache/util.h @@ -55,7 +55,8 @@ struct OverlapResult {  [[nodiscard]] std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst,                                                             const ImageInfo& src, -                                                           SubresourceBase base); +                                                           SubresourceBase base, u32 up_scale = 1, +                                                           u32 down_shift = 0);  [[nodiscard]] bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config); | 
