Texture_Cache: Initial Implementation of Resolution Scaling
This commit is contained in:
committed by
FernandoS27
parent
b9f21e44ad
commit
e1a86c2abc
@@ -421,7 +421,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
|
|||||||
texture_cache.GuardRenderTargets(false);
|
texture_cache.GuardRenderTargets(false);
|
||||||
|
|
||||||
state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey);
|
state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey);
|
||||||
SyncViewport(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
|
void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
|
||||||
@@ -547,9 +546,11 @@ void RasterizerOpenGL::Clear() {
|
|||||||
|
|
||||||
ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil);
|
ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil);
|
||||||
|
|
||||||
SyncViewport(clear_state);
|
bool res_scaling = texture_cache.IsResolutionScalingEnabled();
|
||||||
|
|
||||||
|
SyncViewport(clear_state, res_scaling);
|
||||||
if (regs.clear_flags.scissor) {
|
if (regs.clear_flags.scissor) {
|
||||||
SyncScissorTest(clear_state);
|
SyncScissorTest(clear_state, res_scaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs.clear_flags.viewport) {
|
if (regs.clear_flags.viewport) {
|
||||||
@@ -584,7 +585,6 @@ void RasterizerOpenGL::DrawPrelude() {
|
|||||||
SyncLogicOpState();
|
SyncLogicOpState();
|
||||||
SyncCullMode();
|
SyncCullMode();
|
||||||
SyncPrimitiveRestart();
|
SyncPrimitiveRestart();
|
||||||
SyncScissorTest(state);
|
|
||||||
SyncTransformFeedback();
|
SyncTransformFeedback();
|
||||||
SyncPointState();
|
SyncPointState();
|
||||||
SyncPolygonOffset();
|
SyncPolygonOffset();
|
||||||
@@ -641,6 +641,10 @@ void RasterizerOpenGL::DrawPrelude() {
|
|||||||
gpu.dirty.ResetVertexArrays();
|
gpu.dirty.ResetVertexArrays();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool res_scaling = texture_cache.IsResolutionScalingEnabled();
|
||||||
|
SyncViewport(state, res_scaling);
|
||||||
|
SyncScissorTest(state, res_scaling);
|
||||||
|
|
||||||
shader_program_manager->SetConstants(gpu);
|
shader_program_manager->SetConstants(gpu);
|
||||||
shader_program_manager->ApplyTo(state);
|
shader_program_manager->ApplyTo(state);
|
||||||
state.Apply();
|
state.Apply();
|
||||||
@@ -1063,20 +1067,21 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
|
|||||||
state.images[binding] = view->GetTexture();
|
state.images[binding] = view->GetTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
|
void RasterizerOpenGL::SyncViewport(OpenGLState& current_state, bool rescaling) {
|
||||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||||
const bool geometry_shaders_enabled =
|
const bool geometry_shaders_enabled =
|
||||||
regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
|
regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
|
||||||
const std::size_t viewport_count =
|
const std::size_t viewport_count =
|
||||||
geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
|
geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
|
||||||
|
float factor = rescaling ? Settings::values.resolution_factor : 1.0;
|
||||||
for (std::size_t i = 0; i < viewport_count; i++) {
|
for (std::size_t i = 0; i < viewport_count; i++) {
|
||||||
auto& viewport = current_state.viewports[i];
|
auto& viewport = current_state.viewports[i];
|
||||||
const auto& src = regs.viewports[i];
|
const auto& src = regs.viewports[i];
|
||||||
const Common::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
|
const Common::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
|
||||||
viewport.x = viewport_rect.left;
|
viewport.x = viewport_rect.left * factor;
|
||||||
viewport.y = viewport_rect.bottom;
|
viewport.y = viewport_rect.bottom * factor;
|
||||||
viewport.width = viewport_rect.GetWidth();
|
viewport.width = viewport_rect.GetWidth() * factor;
|
||||||
viewport.height = viewport_rect.GetHeight();
|
viewport.height = viewport_rect.GetHeight() * factor;
|
||||||
viewport.depth_range_far = src.depth_range_far;
|
viewport.depth_range_far = src.depth_range_far;
|
||||||
viewport.depth_range_near = src.depth_range_near;
|
viewport.depth_range_near = src.depth_range_near;
|
||||||
}
|
}
|
||||||
@@ -1287,12 +1292,13 @@ void RasterizerOpenGL::SyncLogicOpState() {
|
|||||||
state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation);
|
state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncScissorTest(OpenGLState& current_state) {
|
void RasterizerOpenGL::SyncScissorTest(OpenGLState& current_state, bool rescaling) {
|
||||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||||
const bool geometry_shaders_enabled =
|
const bool geometry_shaders_enabled =
|
||||||
regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
|
regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
|
||||||
const std::size_t viewport_count =
|
const std::size_t viewport_count =
|
||||||
geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
|
geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
|
||||||
|
float factor = rescaling ? Settings::values.resolution_factor : 1.0;
|
||||||
for (std::size_t i = 0; i < viewport_count; i++) {
|
for (std::size_t i = 0; i < viewport_count; i++) {
|
||||||
const auto& src = regs.scissor_test[i];
|
const auto& src = regs.scissor_test[i];
|
||||||
auto& dst = current_state.viewports[i].scissor;
|
auto& dst = current_state.viewports[i].scissor;
|
||||||
@@ -1302,10 +1308,10 @@ void RasterizerOpenGL::SyncScissorTest(OpenGLState& current_state) {
|
|||||||
}
|
}
|
||||||
const u32 width = src.max_x - src.min_x;
|
const u32 width = src.max_x - src.min_x;
|
||||||
const u32 height = src.max_y - src.min_y;
|
const u32 height = src.max_y - src.min_y;
|
||||||
dst.x = src.min_x;
|
dst.x = src.min_x * factor;
|
||||||
dst.y = src.min_y;
|
dst.y = src.min_y * factor;
|
||||||
dst.width = width;
|
dst.width = width * factor;
|
||||||
dst.height = height;
|
dst.height = height * factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ private:
|
|||||||
const GLShader::ImageEntry& entry);
|
const GLShader::ImageEntry& entry);
|
||||||
|
|
||||||
/// Syncs the viewport and depth range to match the guest state
|
/// Syncs the viewport and depth range to match the guest state
|
||||||
void SyncViewport(OpenGLState& current_state);
|
void SyncViewport(OpenGLState& current_state, bool rescaling = false);
|
||||||
|
|
||||||
/// Syncs the clip enabled status to match the guest state
|
/// Syncs the clip enabled status to match the guest state
|
||||||
void SyncClipEnabled(
|
void SyncClipEnabled(
|
||||||
@@ -162,7 +162,7 @@ private:
|
|||||||
void SyncMultiSampleState();
|
void SyncMultiSampleState();
|
||||||
|
|
||||||
/// Syncs the scissor test state to match the guest state
|
/// Syncs the scissor test state to match the guest state
|
||||||
void SyncScissorTest(OpenGLState& current_state);
|
void SyncScissorTest(OpenGLState& current_state, bool rescaling = false);
|
||||||
|
|
||||||
/// Syncs the transform feedback state to match the guest state
|
/// Syncs the transform feedback state to match the guest state
|
||||||
void SyncTransformFeedback();
|
void SyncTransformFeedback();
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ void ApplyTextureDefaults(const SurfaceParams& params, GLuint texture) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum internal_format,
|
OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum internal_format,
|
||||||
OGLBuffer& texture_buffer) {
|
OGLBuffer& texture_buffer, float resolution_factor) {
|
||||||
OGLTexture texture;
|
OGLTexture texture;
|
||||||
texture.Create(target);
|
texture.Create(target);
|
||||||
|
|
||||||
@@ -214,6 +214,9 @@ OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum inte
|
|||||||
glTextureBuffer(texture.handle, internal_format, texture_buffer.handle);
|
glTextureBuffer(texture.handle, internal_format, texture_buffer.handle);
|
||||||
break;
|
break;
|
||||||
case SurfaceTarget::Texture2D:
|
case SurfaceTarget::Texture2D:
|
||||||
|
glTextureStorage2D(texture.handle, params.emulated_levels, internal_format,
|
||||||
|
params.width * resolution_factor, params.height * resolution_factor);
|
||||||
|
break;
|
||||||
case SurfaceTarget::TextureCubemap:
|
case SurfaceTarget::TextureCubemap:
|
||||||
glTextureStorage2D(texture.handle, params.emulated_levels, internal_format, params.width,
|
glTextureStorage2D(texture.handle, params.emulated_levels, internal_format, params.width,
|
||||||
params.height);
|
params.height);
|
||||||
@@ -242,8 +245,12 @@ CachedSurface::CachedSurface(const GPUVAddr gpu_addr, const SurfaceParams& param
|
|||||||
format = tuple.format;
|
format = tuple.format;
|
||||||
type = tuple.type;
|
type = tuple.type;
|
||||||
is_compressed = tuple.compressed;
|
is_compressed = tuple.compressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachedSurface::Init() {
|
||||||
target = GetTextureTarget(params.target);
|
target = GetTextureTarget(params.target);
|
||||||
texture = CreateTexture(params, target, internal_format, texture_buffer);
|
float resolution_factor = IsRescaled() ? Settings::values.resolution_factor : 1.0;
|
||||||
|
texture = CreateTexture(params, target, internal_format, texture_buffer, resolution_factor);
|
||||||
DecorateSurfaceName();
|
DecorateSurfaceName();
|
||||||
main_view = CreateViewInner(
|
main_view = CreateViewInner(
|
||||||
ViewParams(params.target, 0, params.is_layered ? params.depth : 1, 0, params.num_levels),
|
ViewParams(params.target, 0, params.is_layered ? params.depth : 1, 0, params.num_levels),
|
||||||
@@ -325,6 +332,7 @@ void CachedSurface::UploadTextureMipmap(u32 level, const std::vector<u8>& stagin
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
float resolution_factor = IsRescaled() ? Settings::values.resolution_factor : 1.0;
|
||||||
switch (params.target) {
|
switch (params.target) {
|
||||||
case SurfaceTarget::Texture1D:
|
case SurfaceTarget::Texture1D:
|
||||||
glTextureSubImage1D(texture.handle, level, 0, params.GetMipWidth(level), format, type,
|
glTextureSubImage1D(texture.handle, level, 0, params.GetMipWidth(level), format, type,
|
||||||
@@ -337,8 +345,9 @@ void CachedSurface::UploadTextureMipmap(u32 level, const std::vector<u8>& stagin
|
|||||||
break;
|
break;
|
||||||
case SurfaceTarget::Texture1DArray:
|
case SurfaceTarget::Texture1DArray:
|
||||||
case SurfaceTarget::Texture2D:
|
case SurfaceTarget::Texture2D:
|
||||||
glTextureSubImage2D(texture.handle, level, 0, 0, params.GetMipWidth(level),
|
glTextureSubImage2D(
|
||||||
params.GetMipHeight(level), format, type, buffer);
|
texture.handle, level, 0, 0, params.GetMipWidth(level) * resolution_factor,
|
||||||
|
params.GetMipHeight(level) * resolution_factor, format, type, buffer);
|
||||||
break;
|
break;
|
||||||
case SurfaceTarget::Texture3D:
|
case SurfaceTarget::Texture3D:
|
||||||
case SurfaceTarget::Texture2DArray:
|
case SurfaceTarget::Texture2DArray:
|
||||||
@@ -461,7 +470,10 @@ TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system,
|
|||||||
TextureCacheOpenGL::~TextureCacheOpenGL() = default;
|
TextureCacheOpenGL::~TextureCacheOpenGL() = default;
|
||||||
|
|
||||||
Surface TextureCacheOpenGL::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) {
|
Surface TextureCacheOpenGL::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) {
|
||||||
return std::make_shared<CachedSurface>(gpu_addr, params);
|
Surface new_surface = std::make_shared<CachedSurface>(gpu_addr, params);
|
||||||
|
SignalCreatedSurface(new_surface);
|
||||||
|
new_surface->Init();
|
||||||
|
return new_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCacheOpenGL::ImageCopy(Surface& src_surface, Surface& dst_surface,
|
void TextureCacheOpenGL::ImageCopy(Surface& src_surface, Surface& dst_surface,
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public:
|
|||||||
explicit CachedSurface(GPUVAddr gpu_addr, const SurfaceParams& params);
|
explicit CachedSurface(GPUVAddr gpu_addr, const SurfaceParams& params);
|
||||||
~CachedSurface();
|
~CachedSurface();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
|
||||||
void UploadTexture(const std::vector<u8>& staging_buffer) override;
|
void UploadTexture(const std::vector<u8>& staging_buffer) override;
|
||||||
void DownloadTexture(std::vector<u8>& staging_buffer) override;
|
void DownloadTexture(std::vector<u8>& staging_buffer) override;
|
||||||
|
|
||||||
|
|||||||
68
src/video_core/texture_cache/resolution_scaling/database.h
Normal file
68
src/video_core/texture_cache/resolution_scaling/database.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright 2019 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
#include "video_core/surface.h"
|
||||||
|
|
||||||
|
namespace VideoCommon::Resolution {
|
||||||
|
|
||||||
|
using VideoCore::Surface::PixelFormat;
|
||||||
|
|
||||||
|
struct ResolutionKey {
|
||||||
|
PixelFormat format;
|
||||||
|
u32 width;
|
||||||
|
u32 height;
|
||||||
|
std::size_t Hash() const {
|
||||||
|
const std::size_t comp1 = static_cast<std::size_t>(format) << 44;
|
||||||
|
const std::size_t comp2 = static_cast<std::size_t>(height) << 24;
|
||||||
|
const std::size_t comp3 = static_cast<std::size_t>(width);
|
||||||
|
return comp1 | comp2 | comp3;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ResolutionKey& ks) const {
|
||||||
|
return std::tie(format, width, height) == std::tie(ks.format, ks.width, ks.height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace VideoCommon::Resolution
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<VideoCommon::Resolution::ResolutionKey> {
|
||||||
|
std::size_t operator()(const VideoCommon::Resolution::ResolutionKey& k) const {
|
||||||
|
return k.Hash();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
namespace VideoCommon::Resolution {
|
||||||
|
|
||||||
|
class ScalingDatabase {
|
||||||
|
public:
|
||||||
|
explicit ScalingDatabase() : database{} {}
|
||||||
|
|
||||||
|
bool IsInDatabase(const PixelFormat format, const u32 width, const u32 height) {
|
||||||
|
ResolutionKey key{format, width, height};
|
||||||
|
return database.count(key) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register(const PixelFormat format, const u32 width, const u32 height) {
|
||||||
|
ResolutionKey key{format, width, height};
|
||||||
|
database.insert(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unregister(const PixelFormat format, const u32 width, const u32 height) {
|
||||||
|
ResolutionKey key{format, width, height};
|
||||||
|
database.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_set<ResolutionKey> database;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace VideoCommon::Resolution
|
||||||
@@ -205,6 +205,10 @@ public:
|
|||||||
index = index_;
|
index = index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MarkAsRescaled(const bool is_rescaled) {
|
||||||
|
this->is_rescaled = is_rescaled;
|
||||||
|
}
|
||||||
|
|
||||||
void MarkAsPicked(bool is_picked_) {
|
void MarkAsPicked(bool is_picked_) {
|
||||||
is_picked = is_picked_;
|
is_picked = is_picked_;
|
||||||
}
|
}
|
||||||
@@ -226,6 +230,10 @@ public:
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsRescaled() const {
|
||||||
|
return is_rescaled;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsRegistered() const {
|
bool IsRegistered() const {
|
||||||
return is_registered;
|
return is_registered;
|
||||||
}
|
}
|
||||||
@@ -318,6 +326,7 @@ private:
|
|||||||
bool is_target{};
|
bool is_target{};
|
||||||
bool is_registered{};
|
bool is_registered{};
|
||||||
bool is_picked{};
|
bool is_picked{};
|
||||||
|
bool is_rescaled{};
|
||||||
u32 index{NO_RT};
|
u32 index{NO_RT};
|
||||||
u64 modification_tick{};
|
u64 modification_tick{};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "video_core/rasterizer_interface.h"
|
#include "video_core/rasterizer_interface.h"
|
||||||
#include "video_core/surface.h"
|
#include "video_core/surface.h"
|
||||||
#include "video_core/texture_cache/copy_params.h"
|
#include "video_core/texture_cache/copy_params.h"
|
||||||
|
#include "video_core/texture_cache/resolution_scaling/database.h"
|
||||||
#include "video_core/texture_cache/surface_base.h"
|
#include "video_core/texture_cache/surface_base.h"
|
||||||
#include "video_core/texture_cache/surface_params.h"
|
#include "video_core/texture_cache/surface_params.h"
|
||||||
#include "video_core/texture_cache/surface_view.h"
|
#include "video_core/texture_cache/surface_view.h"
|
||||||
@@ -254,6 +255,39 @@ public:
|
|||||||
return ++ticks;
|
return ++ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsResolutionScalingEnabled() const {
|
||||||
|
if (!EnabledRescaling()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
u32 enabled_targets = 0;
|
||||||
|
u32 rescaled_targets = 0;
|
||||||
|
bool rescaling = false;
|
||||||
|
for (const auto& target : render_targets) {
|
||||||
|
if (target.target) {
|
||||||
|
enabled_targets++;
|
||||||
|
if (target.target->IsRescaled()) {
|
||||||
|
rescaling = true;
|
||||||
|
rescaled_targets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (depth_buffer.target) {
|
||||||
|
enabled_targets++;
|
||||||
|
if (depth_buffer.target->IsRescaled()) {
|
||||||
|
rescaling = true;
|
||||||
|
rescaled_targets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rescaling) {
|
||||||
|
if (rescaled_targets != enabled_targets) {
|
||||||
|
LOG_CRITICAL(HW_GPU, "Rescaling Database is incorrectly set! Redo the database.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
|
TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
|
||||||
: system{system}, rasterizer{rasterizer} {
|
: system{system}, rasterizer{rasterizer} {
|
||||||
@@ -353,6 +387,16 @@ protected:
|
|||||||
return GetSurface(gpu_addr, params, true, false);
|
return GetSurface(gpu_addr, params, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must be called by child's create surface
|
||||||
|
void SignalCreatedSurface(TSurface& new_surface) {
|
||||||
|
const auto& params = new_surface->GetSurfaceParams();
|
||||||
|
if (guard_render_targets && EnabledRescaling()) {
|
||||||
|
if (scaling_database.IsInDatabase(params.pixel_format, params.width, params.height)) {
|
||||||
|
new_surface->MarkAsRescaled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -924,6 +968,10 @@ private:
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EnabledRescaling() const {
|
||||||
|
return Settings::values.resolution_factor != 1.0; //|| Settings::values.res_scanning
|
||||||
|
}
|
||||||
|
|
||||||
constexpr PixelFormat GetSiblingFormat(PixelFormat format) const {
|
constexpr PixelFormat GetSiblingFormat(PixelFormat format) const {
|
||||||
return siblings_table[static_cast<std::size_t>(format)];
|
return siblings_table[static_cast<std::size_t>(format)];
|
||||||
}
|
}
|
||||||
@@ -972,6 +1020,8 @@ private:
|
|||||||
|
|
||||||
StagingCache staging_cache;
|
StagingCache staging_cache;
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
|
|
||||||
|
Resolution::ScalingDatabase scaling_database;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace VideoCommon
|
} // namespace VideoCommon
|
||||||
|
|||||||
Reference in New Issue
Block a user