From 22f4b290b6f0894d29302102f539dd8753961f04 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 18 Jul 2021 18:40:14 +0200 Subject: VideoCore: Initial Setup for the Resolution Scaler. --- src/video_core/texture_cache/image_base.h | 4 + src/video_core/texture_cache/image_info.h | 2 +- src/video_core/texture_cache/texture_cache.h | 113 +++++++++++++++++++++- src/video_core/texture_cache/texture_cache_base.h | 10 ++ 4 files changed, 126 insertions(+), 3 deletions(-) (limited to 'src/video_core/texture_cache') diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index 0c17a791b..1cd30fd37 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h @@ -33,6 +33,10 @@ enum class ImageFlagBits : u32 { ///< garbage collection priority Alias = 1 << 11, ///< This image has aliases and has priority on garbage ///< collection + + // Rescaler + Rescaled = 1 << 12, + RescaleChecked = 1 << 13, }; DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h index 5049fc36e..16d4cee37 100644 --- a/src/video_core/texture_cache/image_info.h +++ b/src/video_core/texture_cache/image_info.h @@ -15,7 +15,7 @@ using Tegra::Texture::TICEntry; using VideoCore::Surface::PixelFormat; struct ImageInfo { - explicit ImageInfo() = default; + ImageInfo() = default; explicit ImageInfo(const TICEntry& config) noexcept; explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept; explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index f70c1f764..560da4f16 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -35,6 +35,7 @@ TextureCache
::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& Tegra::MemoryManager& gpu_memory_) : runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_} { + runtime.Init(); // Configure null sampler TSCEntry sampler_descriptor{}; sampler_descriptor.min_filter.Assign(Tegra::Texture::TextureFilter::Linear); @@ -103,6 +104,7 @@ void TextureCache
::TickFrame() { sentenced_images.Tick(); sentenced_framebuffers.Tick(); sentenced_image_view.Tick(); + runtime.TickFrame(); ++frame_tick; } @@ -208,18 +210,63 @@ void TextureCache
::UpdateRenderTargets(bool is_clear) {
const bool force = flags[Dirty::RenderTargetControl];
flags[Dirty::RenderTargetControl] = false;
+ bool can_rescale = true;
+ std::array ::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
return image_id;
}
+template ::ImageCanRescale(Image& image) {
+ if (True(image.flags & ImageFlagBits::Rescaled) ||
+ True(image.flags & ImageFlagBits::RescaleChecked)) {
+ return true;
+ }
+ const auto& info = image.info;
+ const bool can_this_rescale =
+ (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
+ if (!can_this_rescale) {
+ image.flags &= ~ImageFlagBits::RescaleChecked;
+ return false;
+ }
+ image.flags |= ImageFlagBits::RescaleChecked;
+ for (const auto& alias : image.aliased_images) {
+ Image& other_image = slot_images[alias.id];
+ if (!ImageCanRescale(other_image)) {
+ image.flags &= ~ImageFlagBits::RescaleChecked;
+ return false;
+ }
+ }
+ image.flags &= ~ImageFlagBits::RescaleChecked;
+ return true;
+}
+
template ::InsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
RelaxedOptions options) {
@@ -660,12 +732,18 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
std::vector ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
cpu_addr = solution->cpu_addr;
new_info.resources = solution->resources;
overlap_ids.push_back(overlap_id);
+ all_siblings.push_back(overlap_id);
return;
}
static constexpr auto options = RelaxedOptions::Size | RelaxedOptions::Format;
@@ -688,10 +767,12 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
if (IsSubresource(new_info, overlap, gpu_addr, options, broken_views, native_bgr)) {
left_aliased_ids.push_back(overlap_id);
overlap.flags |= ImageFlagBits::Alias;
+ all_siblings.push_back(overlap_id);
} else if (IsSubresource(overlap.info, new_image_base, overlap.gpu_addr, options,
broken_views, native_bgr)) {
right_aliased_ids.push_back(overlap_id);
overlap.flags |= ImageFlagBits::Alias;
+ all_siblings.push_back(overlap_id);
} else {
bad_overlap_ids.push_back(overlap_id);
overlap.flags |= ImageFlagBits::BadOverlap;
@@ -709,8 +790,36 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
}
};
ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu);
+
+ bool can_rescale =
+ (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
+ for (const ImageId sibling_id : all_siblings) {
+ if (!can_rescale) {
+ break;
+ }
+ Image& sibling = slot_images[sibling_id];
+ can_rescale &= ImageCanRescale(sibling);
+ }
+
+ if (can_rescale) {
+ for (const ImageId sibling_id : all_siblings) {
+ Image& sibling = slot_images[sibling_id];
+ sibling.ScaleUp();
+ }
+ } else {
+ for (const ImageId sibling_id : all_siblings) {
+ Image& sibling = slot_images[sibling_id];
+ sibling.ScaleDown();
+ }
+ }
+
const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr);
Image& new_image = slot_images[new_image_id];
+ if (can_rescale) {
+ new_image.ScaleUp();
+ } else {
+ new_image.ScaleDown();
+ }
if (!gpu_memory.IsContinousRange(new_image.gpu_addr, new_image.guest_size_bytes)) {
new_image.flags |= ImageFlagBits::Sparse;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 2d1893c1c..a4a2c0832 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -142,6 +142,14 @@ public:
const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Config& copy);
+ /// Invalidate the contents of the color buffer index
+ /// These contents become unspecified, the cache can assume aggressive optimizations.
+ void InvalidateColorBuffer(size_t index);
+
+ /// Invalidate the contents of the depth buffer
+ /// These contents become unspecified, the cache can assume aggressive optimizations.
+ void InvalidateDepthBuffer();
+
/// Try to find a cached image view in the given CPU address
[[nodiscard]] ImageView* TryFindFramebufferImageView(VAddr cpu_addr);
@@ -318,6 +326,8 @@ private:
/// Returns true if the current clear parameters clear the whole image of a given image view
[[nodiscard]] bool IsFullClear(ImageViewId id);
+ bool ImageCanRescale(Image& image);
+
Runtime& runtime;
VideoCore::RasterizerInterface& rasterizer;
Tegra::Engines::Maxwell3D& maxwell3d;
--
cgit v1.2.3