mirror of
https://github.com/citra-emu/citra.git
synced 2025-02-20 02:20:07 +00:00
integer res_scale and cleanup
This commit is contained in:
parent
96861c6347
commit
926abc6ddb
@ -88,7 +88,7 @@ void Config::ReadValues() {
|
|||||||
Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true);
|
Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true);
|
||||||
Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true);
|
Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true);
|
||||||
Settings::values.resolution_factor =
|
Settings::values.resolution_factor =
|
||||||
(float)sdl2_config->GetReal("Renderer", "resolution_factor", 1.0);
|
static_cast<u16>(sdl2_config->GetInteger("Renderer", "resolution_factor", 1));
|
||||||
Settings::values.use_vsync = sdl2_config->GetBoolean("Renderer", "use_vsync", false);
|
Settings::values.use_vsync = sdl2_config->GetBoolean("Renderer", "use_vsync", false);
|
||||||
Settings::values.toggle_framelimit =
|
Settings::values.toggle_framelimit =
|
||||||
sdl2_config->GetBoolean("Renderer", "toggle_framelimit", true);
|
sdl2_config->GetBoolean("Renderer", "toggle_framelimit", true);
|
||||||
|
@ -73,7 +73,8 @@ void Config::ReadValues() {
|
|||||||
qt_config->beginGroup("Renderer");
|
qt_config->beginGroup("Renderer");
|
||||||
Settings::values.use_hw_renderer = qt_config->value("use_hw_renderer", true).toBool();
|
Settings::values.use_hw_renderer = qt_config->value("use_hw_renderer", true).toBool();
|
||||||
Settings::values.use_shader_jit = qt_config->value("use_shader_jit", true).toBool();
|
Settings::values.use_shader_jit = qt_config->value("use_shader_jit", true).toBool();
|
||||||
Settings::values.resolution_factor = qt_config->value("resolution_factor", 1.0).toFloat();
|
Settings::values.resolution_factor =
|
||||||
|
static_cast<u16>(qt_config->value("resolution_factor", 1).toInt());
|
||||||
Settings::values.use_vsync = qt_config->value("use_vsync", false).toBool();
|
Settings::values.use_vsync = qt_config->value("use_vsync", false).toBool();
|
||||||
Settings::values.toggle_framelimit = qt_config->value("toggle_framelimit", true).toBool();
|
Settings::values.toggle_framelimit = qt_config->value("toggle_framelimit", true).toBool();
|
||||||
|
|
||||||
|
@ -20,81 +20,11 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
|||||||
|
|
||||||
ConfigureGraphics::~ConfigureGraphics() {}
|
ConfigureGraphics::~ConfigureGraphics() {}
|
||||||
|
|
||||||
enum class Resolution : int {
|
|
||||||
Auto,
|
|
||||||
Scale1x,
|
|
||||||
Scale2x,
|
|
||||||
Scale3x,
|
|
||||||
Scale4x,
|
|
||||||
Scale5x,
|
|
||||||
Scale6x,
|
|
||||||
Scale7x,
|
|
||||||
Scale8x,
|
|
||||||
Scale9x,
|
|
||||||
Scale10x,
|
|
||||||
};
|
|
||||||
|
|
||||||
float ToResolutionFactor(Resolution option) {
|
|
||||||
switch (option) {
|
|
||||||
case Resolution::Auto:
|
|
||||||
return 0.f;
|
|
||||||
case Resolution::Scale1x:
|
|
||||||
return 1.f;
|
|
||||||
case Resolution::Scale2x:
|
|
||||||
return 2.f;
|
|
||||||
case Resolution::Scale3x:
|
|
||||||
return 3.f;
|
|
||||||
case Resolution::Scale4x:
|
|
||||||
return 4.f;
|
|
||||||
case Resolution::Scale5x:
|
|
||||||
return 5.f;
|
|
||||||
case Resolution::Scale6x:
|
|
||||||
return 6.f;
|
|
||||||
case Resolution::Scale7x:
|
|
||||||
return 7.f;
|
|
||||||
case Resolution::Scale8x:
|
|
||||||
return 8.f;
|
|
||||||
case Resolution::Scale9x:
|
|
||||||
return 9.f;
|
|
||||||
case Resolution::Scale10x:
|
|
||||||
return 10.f;
|
|
||||||
}
|
|
||||||
return 0.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
Resolution FromResolutionFactor(float factor) {
|
|
||||||
if (factor == 0.f) {
|
|
||||||
return Resolution::Auto;
|
|
||||||
} else if (factor == 1.f) {
|
|
||||||
return Resolution::Scale1x;
|
|
||||||
} else if (factor == 2.f) {
|
|
||||||
return Resolution::Scale2x;
|
|
||||||
} else if (factor == 3.f) {
|
|
||||||
return Resolution::Scale3x;
|
|
||||||
} else if (factor == 4.f) {
|
|
||||||
return Resolution::Scale4x;
|
|
||||||
} else if (factor == 5.f) {
|
|
||||||
return Resolution::Scale5x;
|
|
||||||
} else if (factor == 6.f) {
|
|
||||||
return Resolution::Scale6x;
|
|
||||||
} else if (factor == 7.f) {
|
|
||||||
return Resolution::Scale7x;
|
|
||||||
} else if (factor == 8.f) {
|
|
||||||
return Resolution::Scale8x;
|
|
||||||
} else if (factor == 9.f) {
|
|
||||||
return Resolution::Scale9x;
|
|
||||||
} else if (factor == 10.f) {
|
|
||||||
return Resolution::Scale10x;
|
|
||||||
}
|
|
||||||
return Resolution::Auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureGraphics::setConfiguration() {
|
void ConfigureGraphics::setConfiguration() {
|
||||||
ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer);
|
ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer);
|
||||||
ui->resolution_factor_combobox->setEnabled(Settings::values.use_hw_renderer);
|
ui->resolution_factor_combobox->setEnabled(Settings::values.use_hw_renderer);
|
||||||
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit);
|
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit);
|
||||||
ui->resolution_factor_combobox->setCurrentIndex(
|
ui->resolution_factor_combobox->setCurrentIndex(Settings::values.resolution_factor);
|
||||||
static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor)));
|
|
||||||
ui->toggle_vsync->setChecked(Settings::values.use_vsync);
|
ui->toggle_vsync->setChecked(Settings::values.use_vsync);
|
||||||
ui->toggle_framelimit->setChecked(Settings::values.toggle_framelimit);
|
ui->toggle_framelimit->setChecked(Settings::values.toggle_framelimit);
|
||||||
ui->layout_combobox->setCurrentIndex(static_cast<int>(Settings::values.layout_option));
|
ui->layout_combobox->setCurrentIndex(static_cast<int>(Settings::values.layout_option));
|
||||||
@ -105,7 +35,7 @@ void ConfigureGraphics::applyConfiguration() {
|
|||||||
Settings::values.use_hw_renderer = ui->toggle_hw_renderer->isChecked();
|
Settings::values.use_hw_renderer = ui->toggle_hw_renderer->isChecked();
|
||||||
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
|
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
|
||||||
Settings::values.resolution_factor =
|
Settings::values.resolution_factor =
|
||||||
ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex()));
|
static_cast<u16>(ui->resolution_factor_combobox->currentIndex());
|
||||||
Settings::values.use_vsync = ui->toggle_vsync->isChecked();
|
Settings::values.use_vsync = ui->toggle_vsync->isChecked();
|
||||||
Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked();
|
Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked();
|
||||||
Settings::values.layout_option =
|
Settings::values.layout_option =
|
||||||
|
@ -16,8 +16,8 @@ static const float TOP_SCREEN_ASPECT_RATIO =
|
|||||||
static const float BOT_SCREEN_ASPECT_RATIO =
|
static const float BOT_SCREEN_ASPECT_RATIO =
|
||||||
static_cast<float>(Core::kScreenBottomHeight) / Core::kScreenBottomWidth;
|
static_cast<float>(Core::kScreenBottomHeight) / Core::kScreenBottomWidth;
|
||||||
|
|
||||||
float FramebufferLayout::GetScalingRatio() const {
|
u16 FramebufferLayout::GetScalingRatio() const {
|
||||||
return static_cast<float>(top_screen.GetWidth()) / Core::kScreenTopWidth;
|
return static_cast<u16>(((top_screen.GetWidth() - 1) / Core::kScreenTopWidth) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finds the largest size subrectangle contained in window area that is confined to the aspect ratio
|
// Finds the largest size subrectangle contained in window area that is confined to the aspect ratio
|
||||||
|
@ -21,7 +21,7 @@ struct FramebufferLayout {
|
|||||||
* Returns the ration of pixel size of the top screen, compared to the native size of the 3DS
|
* Returns the ration of pixel size of the top screen, compared to the native size of the 3DS
|
||||||
* screen.
|
* screen.
|
||||||
*/
|
*/
|
||||||
float GetScalingRatio() const;
|
u16 GetScalingRatio() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,7 +95,7 @@ struct Values {
|
|||||||
// Renderer
|
// Renderer
|
||||||
bool use_hw_renderer;
|
bool use_hw_renderer;
|
||||||
bool use_shader_jit;
|
bool use_shader_jit;
|
||||||
float resolution_factor;
|
u16 resolution_factor;
|
||||||
bool use_vsync;
|
bool use_vsync;
|
||||||
bool toggle_framelimit;
|
bool toggle_framelimit;
|
||||||
|
|
||||||
|
@ -245,7 +245,7 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||||||
// Sync and bind the framebuffer surfaces
|
// Sync and bind the framebuffer surfaces
|
||||||
Surface color_surface;
|
Surface color_surface;
|
||||||
Surface depth_surface;
|
Surface depth_surface;
|
||||||
MathUtil::Rectangle<int> rect;
|
MathUtil::Rectangle<u32> rect;
|
||||||
std::tie(color_surface, depth_surface, rect) =
|
std::tie(color_surface, depth_surface, rect) =
|
||||||
res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb);
|
res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb);
|
||||||
|
|
||||||
@ -279,37 +279,32 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||||||
const GLsizei viewport_height =
|
const GLsizei viewport_height =
|
||||||
static_cast<GLsizei>(Pica::float24::FromRaw(regs.rasterizer.viewport_size_y).ToFloat32() * 2);
|
static_cast<GLsizei>(Pica::float24::FromRaw(regs.rasterizer.viewport_size_y).ToFloat32() * 2);
|
||||||
|
|
||||||
const float res_scale_width = color_surface != nullptr ? color_surface->res_scale_width :
|
const u16 res_scale = color_surface != nullptr ? color_surface->res_scale :
|
||||||
(depth_surface == nullptr ? 1.0f : depth_surface->res_scale_width);
|
(depth_surface == nullptr ? 1u : depth_surface->res_scale);
|
||||||
const float res_scale_height = color_surface != nullptr ? color_surface->res_scale_height :
|
|
||||||
(depth_surface == nullptr ? 1.0f : depth_surface->res_scale_height);
|
|
||||||
|
|
||||||
glViewport(
|
glViewport(
|
||||||
static_cast<GLint>(rect.left + regs.rasterizer.viewport_corner.x * res_scale_width),
|
static_cast<GLint>(rect.left + regs.rasterizer.viewport_corner.x * res_scale),
|
||||||
static_cast<GLint>(rect.bottom + regs.rasterizer.viewport_corner.y * res_scale_height),
|
static_cast<GLint>(rect.bottom + regs.rasterizer.viewport_corner.y * res_scale),
|
||||||
static_cast<GLsizei>(viewport_width * res_scale_width),
|
viewport_width * res_scale,
|
||||||
static_cast<GLsizei>(viewport_height * res_scale_height));
|
viewport_height * res_scale);
|
||||||
|
|
||||||
if (uniform_block_data.data.framebuffer_scale[0] != res_scale_width ||
|
if (uniform_block_data.data.framebuffer_scale != res_scale) {
|
||||||
uniform_block_data.data.framebuffer_scale[1] != res_scale_height) {
|
uniform_block_data.data.framebuffer_scale = res_scale;
|
||||||
|
|
||||||
uniform_block_data.data.framebuffer_scale[0] = res_scale_width;
|
|
||||||
uniform_block_data.data.framebuffer_scale[1] = res_scale_height;
|
|
||||||
uniform_block_data.dirty = true;
|
uniform_block_data.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scissor checks are window-, not viewport-relative, which means that if the cached texture
|
// Scissor checks are window-, not viewport-relative, which means that if the cached texture
|
||||||
// sub-rect changes, the scissor bounds also need to be updated.
|
// sub-rect changes, the scissor bounds also need to be updated.
|
||||||
GLint scissor_x1 = static_cast<GLint>(
|
GLint scissor_x1 = static_cast<GLint>(
|
||||||
rect.left + regs.rasterizer.scissor_test.x1 * res_scale_width);
|
rect.left + regs.rasterizer.scissor_test.x1 * res_scale);
|
||||||
GLint scissor_y1 = static_cast<GLint>(
|
GLint scissor_y1 = static_cast<GLint>(
|
||||||
rect.bottom + regs.rasterizer.scissor_test.y1 * res_scale_height);
|
rect.bottom + regs.rasterizer.scissor_test.y1 * res_scale);
|
||||||
// x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when
|
// x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when
|
||||||
// scaling or doing multisampling.
|
// scaling or doing multisampling.
|
||||||
GLint scissor_x2 = static_cast<GLint>(
|
GLint scissor_x2 = static_cast<GLint>(
|
||||||
rect.left + (regs.rasterizer.scissor_test.x2 + 1) * res_scale_width);
|
rect.left + (regs.rasterizer.scissor_test.x2 + 1) * res_scale);
|
||||||
GLint scissor_y2 = static_cast<GLint>(
|
GLint scissor_y2 = static_cast<GLint>(
|
||||||
rect.bottom + (regs.rasterizer.scissor_test.y2 + 1) * res_scale_height);
|
rect.bottom + (regs.rasterizer.scissor_test.y2 + 1) * res_scale);
|
||||||
|
|
||||||
if (uniform_block_data.data.scissor_x1 != scissor_x1 ||
|
if (uniform_block_data.data.scissor_x1 != scissor_x1 ||
|
||||||
uniform_block_data.data.scissor_x2 != scissor_x2 ||
|
uniform_block_data.data.scissor_x2 != scissor_x2 ||
|
||||||
@ -959,16 +954,15 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe
|
|||||||
dst_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.output_format);
|
dst_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.output_format);
|
||||||
dst_params.UpdateParams();
|
dst_params.UpdateParams();
|
||||||
|
|
||||||
MathUtil::Rectangle<int> src_rect;
|
MathUtil::Rectangle<u32> src_rect;
|
||||||
Surface src_surface;
|
Surface src_surface;
|
||||||
std::tie(src_surface, src_rect) = res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
|
std::tie(src_surface, src_rect) = res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
|
||||||
if (src_surface == nullptr)
|
if (src_surface == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
dst_params.res_scale_width = src_surface->res_scale_width;
|
dst_params.res_scale = src_surface->res_scale;
|
||||||
dst_params.res_scale_height = src_surface->res_scale_height;
|
|
||||||
|
|
||||||
MathUtil::Rectangle<int> dst_rect;
|
MathUtil::Rectangle<u32> dst_rect;
|
||||||
Surface dst_surface;
|
Surface dst_surface;
|
||||||
std::tie(dst_surface, dst_rect) = res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, false);
|
std::tie(dst_surface, dst_rect) = res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, false);
|
||||||
if (dst_surface == nullptr)
|
if (dst_surface == nullptr)
|
||||||
@ -1004,7 +998,7 @@ bool RasterizerOpenGL::AccelerateTextureCopy(const GPU::Regs::DisplayTransferCon
|
|||||||
src_params.size = ((src_params.height - 1) * src_params.stride) + src_params.width;
|
src_params.size = ((src_params.height - 1) * src_params.stride) + src_params.width;
|
||||||
src_params.end = src_params.addr + src_params.size;
|
src_params.end = src_params.addr + src_params.size;
|
||||||
|
|
||||||
MathUtil::Rectangle<int> src_rect;
|
MathUtil::Rectangle<u32> src_rect;
|
||||||
Surface src_surface;
|
Surface src_surface;
|
||||||
std::tie(src_surface, src_rect) = res_cache.GetTexCopySurface(src_params);
|
std::tie(src_surface, src_rect) = res_cache.GetTexCopySurface(src_params);
|
||||||
if (src_surface == nullptr)
|
if (src_surface == nullptr)
|
||||||
@ -1019,12 +1013,11 @@ bool RasterizerOpenGL::AccelerateTextureCopy(const GPU::Regs::DisplayTransferCon
|
|||||||
dst_params.stride = (output_width + output_gap) * src_surface->stride / src_params.stride;
|
dst_params.stride = (output_width + output_gap) * src_surface->stride / src_params.stride;
|
||||||
dst_params.width = output_width * src_surface->stride / src_params.stride;
|
dst_params.width = output_width * src_surface->stride / src_params.stride;
|
||||||
dst_params.height = src_surface->is_tiled ? src_params.height * 8 : src_params.height;
|
dst_params.height = src_surface->is_tiled ? src_params.height * 8 : src_params.height;
|
||||||
dst_params.res_scale_width = src_surface->res_scale_width;
|
dst_params.res_scale = src_surface->res_scale;
|
||||||
dst_params.res_scale_height = src_surface->res_scale_height;
|
|
||||||
dst_params.UpdateParams();
|
dst_params.UpdateParams();
|
||||||
|
|
||||||
const bool load_gap = output_gap != 0; // Since we are going to invalidate the gap if there is one, we will have to load it first
|
const bool load_gap = output_gap != 0; // Since we are going to invalidate the gap if there is one, we will have to load it first
|
||||||
MathUtil::Rectangle<int> dst_rect;
|
MathUtil::Rectangle<u32> dst_rect;
|
||||||
Surface dst_surface;
|
Surface dst_surface;
|
||||||
std::tie(dst_surface, dst_rect) = res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, load_gap);
|
std::tie(dst_surface, dst_rect) = res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, load_gap);
|
||||||
if (src_surface == nullptr)
|
if (src_surface == nullptr)
|
||||||
@ -1063,7 +1056,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con
|
|||||||
src_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.color_format);
|
src_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.color_format);
|
||||||
src_params.UpdateParams();
|
src_params.UpdateParams();
|
||||||
|
|
||||||
MathUtil::Rectangle<int> src_rect;
|
MathUtil::Rectangle<u32> src_rect;
|
||||||
Surface src_surface;
|
Surface src_surface;
|
||||||
std::tie(src_surface, src_rect) = res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
|
std::tie(src_surface, src_rect) = res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ private:
|
|||||||
// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not.
|
// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not.
|
||||||
// Not following that rule will cause problems on some AMD drivers.
|
// Not following that rule will cause problems on some AMD drivers.
|
||||||
struct UniformData {
|
struct UniformData {
|
||||||
alignas(8) GLvec2 framebuffer_scale;
|
GLint framebuffer_scale;
|
||||||
GLint alphatest_ref;
|
GLint alphatest_ref;
|
||||||
GLfloat depth_scale;
|
GLfloat depth_scale;
|
||||||
GLfloat depth_offset;
|
GLfloat depth_offset;
|
||||||
@ -156,7 +156,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
sizeof(UniformData) == 0x470,
|
sizeof(UniformData) == 0x460,
|
||||||
"The size of the UniformData structure has changed, update the structure in the shader");
|
"The size of the UniformData structure has changed, update the structure in the shader");
|
||||||
static_assert(sizeof(UniformData) < 16384,
|
static_assert(sizeof(UniformData) < 16384,
|
||||||
"UniformData structure must be less than 16kb as per the OpenGL spec");
|
"UniformData structure must be less than 16kb as per the OpenGL spec");
|
||||||
|
@ -179,8 +179,8 @@ static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tup
|
|||||||
cur_state.Apply();
|
cur_state.Apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<int>& src_rect,
|
static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect,
|
||||||
GLuint dst_tex, const MathUtil::Rectangle<int>& dst_rect,
|
GLuint dst_tex, const MathUtil::Rectangle<u32>& dst_rect,
|
||||||
SurfaceType type) {
|
SurfaceType type) {
|
||||||
OpenGLState cur_state = OpenGLState::GetCurState();
|
OpenGLState cur_state = OpenGLState::GetCurState();
|
||||||
|
|
||||||
@ -312,35 +312,23 @@ static bool FillSurface(const Surface& surface, const u8* fill_data) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceParams::SurfaceParams() {
|
MathUtil::Rectangle<u32> CachedSurface::GetSubRect(const SurfaceParams& sub_surface) const {
|
||||||
// todo: metroid needs that for now, "breaks" other stuff
|
|
||||||
// Set the internal resolution, assume the same scaling factor for top and bottom screens
|
|
||||||
float resolution_scale_factor = Settings::values.resolution_factor;
|
|
||||||
if (resolution_scale_factor == 0.0f) {
|
|
||||||
// Auto - scale resolution to the window size
|
|
||||||
resolution_scale_factor = VideoCore::g_emu_window->GetFramebufferLayout().GetScalingRatio();
|
|
||||||
}
|
|
||||||
res_scale_width = resolution_scale_factor;
|
|
||||||
res_scale_height = resolution_scale_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
MathUtil::Rectangle<int> CachedSurface::GetSubRect(const SurfaceParams& sub_surface) const {
|
|
||||||
const u32 begin_pixel_index = PixelsInBytes(sub_surface.addr - addr);
|
const u32 begin_pixel_index = PixelsInBytes(sub_surface.addr - addr);
|
||||||
const int x0 = begin_pixel_index % width;
|
const int x0 = begin_pixel_index % width;
|
||||||
const int y0 = begin_pixel_index / width;
|
const int y0 = begin_pixel_index / width;
|
||||||
|
|
||||||
if (is_tiled)
|
if (is_tiled)
|
||||||
return MathUtil::Rectangle<int>(x0, height - y0 - sub_surface.height, x0 + sub_surface.width, height - y0); // Bottom to top
|
return MathUtil::Rectangle<u32>(x0, height - y0 - sub_surface.height, x0 + sub_surface.width, height - y0); // Bottom to top
|
||||||
|
|
||||||
return MathUtil::Rectangle<int>(x0, y0, x0 + sub_surface.width, y0 + sub_surface.height); // Top to bottom
|
return MathUtil::Rectangle<u32>(x0, y0, x0 + sub_surface.width, y0 + sub_surface.height); // Top to bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
MathUtil::Rectangle<int> CachedSurface::GetScaledSubRect(const SurfaceParams& sub_surface) const {
|
MathUtil::Rectangle<u32> CachedSurface::GetScaledSubRect(const SurfaceParams& sub_surface) const {
|
||||||
auto rect = GetSubRect(sub_surface);
|
auto rect = GetSubRect(sub_surface);
|
||||||
rect.left = static_cast<int>(rect.left * res_scale_width);
|
rect.left = rect.left * res_scale;
|
||||||
rect.right = static_cast<int>(rect.right * res_scale_width);
|
rect.right = rect.right * res_scale;
|
||||||
rect.top = static_cast<int>(rect.top * res_scale_height);
|
rect.top = rect.top * res_scale;
|
||||||
rect.bottom = static_cast<int>(rect.bottom * res_scale_height);
|
rect.bottom = rect.bottom * res_scale;
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,7 +565,7 @@ void CachedSurface::UploadGLTexture() {
|
|||||||
cur_state.Apply();
|
cur_state.Apply();
|
||||||
|
|
||||||
// If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface
|
// If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface
|
||||||
if (res_scale_width != 1.f || res_scale_height != 1.f) {
|
if (res_scale != 1) {
|
||||||
OGLTexture scaled_texture;
|
OGLTexture scaled_texture;
|
||||||
scaled_texture.Create();
|
scaled_texture.Create();
|
||||||
|
|
||||||
@ -604,7 +592,7 @@ void CachedSurface::DownloadGLTexture() {
|
|||||||
|
|
||||||
// If not 1x scale, blit scaled texture to a new 1x texture and use that to flush
|
// If not 1x scale, blit scaled texture to a new 1x texture and use that to flush
|
||||||
OGLTexture unscaled_tex;
|
OGLTexture unscaled_tex;
|
||||||
if (res_scale_width != 1.f || res_scale_height != 1.f) {
|
if (res_scale != 1) {
|
||||||
unscaled_tex.Create();
|
unscaled_tex.Create();
|
||||||
|
|
||||||
AllocateSurfaceTexture(unscaled_tex.handle, tuple, width, height);
|
AllocateSurfaceTexture(unscaled_tex.handle, tuple, width, height);
|
||||||
@ -626,65 +614,58 @@ void CachedSurface::DownloadGLTexture() {
|
|||||||
gl_buffer_dirty = false;
|
gl_buffer_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MatchType : int {
|
enum MatchFlags {
|
||||||
Exact = (1 << 0), // Surfaces perfectly match
|
Invalid = 1, // Flag that can be applied to other match types, invalid matches require validation before they can be used
|
||||||
SubRect = (1 << 1), // Surface encompasses params
|
Exact = 1 << 1, // Surfaces perfectly match
|
||||||
Invalid = (1 << 2), // Flag that can be applied to other match types, invalid matches require validation before they can be used
|
SubRect = 1 << 2, // Surface encompasses params
|
||||||
Copy = (1 << 3), // Surface we can copy from
|
Copy = 1 << 3, // Surface we can copy from
|
||||||
//PartialCopy = (1 << 4), // Surface we can partialy copy from
|
TexCopy = 1 << 4 // Surface that will match a display transfer "texture copy" parameters
|
||||||
TexCopy = (1 << 5), // Surface that will match a display transfer "texture copy" parameters
|
|
||||||
All = (1 << 6) - 1,
|
|
||||||
None = 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr MatchType operator | (MatchType lhs, MatchType rhs) {
|
constexpr MatchFlags operator | (MatchFlags lhs, MatchFlags rhs) {
|
||||||
return static_cast<MatchType>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
return static_cast<MatchFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the best surface match (and its match type) for the given flags, higher flag value meaning lower priority
|
/// Get the best surface match (and its match type) for the given flags
|
||||||
/// NEW:: no more match type priority, only region validity matters and then scaling comparison
|
template <MatchFlags find_flags>
|
||||||
template <MatchType find_flags>
|
Surface FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& params, ScaleMatch match_scale_type) {
|
||||||
Surface FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& params, ScaleMatch match_res_scale) {
|
|
||||||
constexpr float MATCH_GOODNESS_RESET = -1.f;
|
|
||||||
|
|
||||||
Surface match_surface = nullptr;
|
Surface match_surface = nullptr;
|
||||||
bool match_valid = false;
|
bool match_valid = false;
|
||||||
float best_match_goodness = MATCH_GOODNESS_RESET;
|
u32 match_scale = 0;
|
||||||
|
|
||||||
for (auto& pair : RangeFromInterval(surface_cache, params.GetInterval())) {
|
for (auto& pair : RangeFromInterval(surface_cache, params.GetInterval())) {
|
||||||
for (auto& surface : pair.second) {
|
for (auto& surface : pair.second) {
|
||||||
const bool res_scale_match = match_res_scale == ScaleMatch::Exact ?
|
const bool res_scale_matched = match_scale_type == ScaleMatch::Exact ?
|
||||||
(params.res_scale_width == surface->res_scale_width && params.res_scale_height == surface->res_scale_height) :
|
(params.res_scale == surface->res_scale) :
|
||||||
(params.res_scale_width <= surface->res_scale_width && params.res_scale_height <= surface->res_scale_height);
|
(params.res_scale <= surface->res_scale);
|
||||||
const float match_goodness = surface->res_scale_width * surface->res_scale_height;
|
|
||||||
const bool is_valid = surface->IsRegionValid(params.GetInterval());
|
const bool is_valid = surface->IsRegionValid(params.GetInterval());
|
||||||
|
|
||||||
if (!(find_flags & MatchType::Invalid) && !is_valid)
|
if (!(find_flags & MatchFlags::Invalid) && !is_valid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto IsMatch_Helper = [&](MatchType check_type, auto match_fn) {
|
const auto IsMatch_Helper = [&](MatchFlags check_type, auto match_fn) {
|
||||||
if (!(find_flags & check_type))
|
if (!(find_flags & check_type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!match_fn())
|
if (!match_fn())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (match_res_scale == ScaleMatch::Ignore || res_scale_match || surface->type == SurfaceType::Fill) { // Found a match
|
if (match_scale_type == ScaleMatch::Ignore || res_scale_matched || surface->type == SurfaceType::Fill) { // Found a match
|
||||||
if (is_valid && !match_valid) {
|
if (is_valid && !match_valid) {
|
||||||
best_match_goodness = MATCH_GOODNESS_RESET;
|
match_scale = 0;
|
||||||
match_valid = true;
|
match_valid = true;
|
||||||
}
|
}
|
||||||
if (match_goodness > best_match_goodness) {
|
if (surface->res_scale > match_scale) {
|
||||||
best_match_goodness = match_goodness;
|
match_scale = surface->res_scale;
|
||||||
match_surface = surface;
|
match_surface = surface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
IsMatch_Helper(MatchType::Exact, [&] { return surface->ExactMatch(params); });
|
IsMatch_Helper(MatchFlags::Exact, [&] { return surface->ExactMatch(params); });
|
||||||
IsMatch_Helper(MatchType::SubRect, [&] { return surface->CanSubRect(params); });
|
IsMatch_Helper(MatchFlags::SubRect, [&] { return surface->CanSubRect(params); });
|
||||||
IsMatch_Helper(MatchType::Copy, [&] { return surface->CanCopy(params); });
|
IsMatch_Helper(MatchFlags::Copy, [&] { return surface->CanCopy(params); });
|
||||||
IsMatch_Helper(MatchType::TexCopy, [&] { return surface->CanTexCopy(params); });
|
IsMatch_Helper(MatchFlags::TexCopy, [&] { return surface->CanTexCopy(params); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return match_surface;
|
return match_surface;
|
||||||
@ -704,9 +685,9 @@ RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface,
|
bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface,
|
||||||
const MathUtil::Rectangle<int>& src_rect,
|
const MathUtil::Rectangle<u32>& src_rect,
|
||||||
const Surface& dst_surface,
|
const Surface& dst_surface,
|
||||||
const MathUtil::Rectangle<int>& dst_rect) {
|
const MathUtil::Rectangle<u32>& dst_rect) {
|
||||||
if (!SurfaceParams::CheckFormatsBlittable(src_surface->pixel_format,
|
if (!SurfaceParams::CheckFormatsBlittable(src_surface->pixel_format,
|
||||||
dst_surface->pixel_format))
|
dst_surface->pixel_format))
|
||||||
return false;
|
return false;
|
||||||
@ -722,7 +703,7 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for an exact or subrect match in existing surfaces
|
// Check for an exact or subrect match in existing surfaces
|
||||||
Surface surface_match = FindMatch<MatchType::Exact | MatchType::Invalid>(surface_cache, params, match_res_scale);
|
Surface surface_match = FindMatch<MatchFlags::Exact | MatchFlags::Invalid>(surface_cache, params, match_res_scale);
|
||||||
|
|
||||||
if (surface_match != nullptr) {
|
if (surface_match != nullptr) {
|
||||||
if (load_if_create) {
|
if (load_if_create) {
|
||||||
@ -745,14 +726,14 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatc
|
|||||||
SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params,
|
SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params,
|
||||||
ScaleMatch match_res_scale,
|
ScaleMatch match_res_scale,
|
||||||
bool load_if_create) {
|
bool load_if_create) {
|
||||||
MathUtil::Rectangle<int> out_rect{};
|
MathUtil::Rectangle<u32> out_rect{};
|
||||||
|
|
||||||
if (params.addr == 0 || params.height * params.width == 0) {
|
if (params.addr == 0 || params.height * params.width == 0) {
|
||||||
return std::make_tuple(nullptr, out_rect);
|
return std::make_tuple(nullptr, out_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to find encompassing surface
|
// Attempt to find encompassing surface
|
||||||
Surface subrect_match = FindMatch<MatchType::SubRect | MatchType::Invalid>(surface_cache, params, match_res_scale);
|
Surface subrect_match = FindMatch<MatchFlags::SubRect | MatchFlags::Invalid>(surface_cache, params, match_res_scale);
|
||||||
|
|
||||||
// Return the best subrect surface if found
|
// Return the best subrect surface if found
|
||||||
if (subrect_match != nullptr) {
|
if (subrect_match != nullptr) {
|
||||||
@ -778,7 +759,7 @@ SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams&
|
|||||||
std::swap(out_rect.top, out_rect.bottom);
|
std::swap(out_rect.top, out_rect.bottom);
|
||||||
|
|
||||||
// If stride was bigger than width we need to adjust our output rect
|
// If stride was bigger than width we need to adjust our output rect
|
||||||
out_rect.right = static_cast<int>(params.width * new_params.res_scale_width);
|
out_rect.right = static_cast<int>(params.width * new_params.res_scale);
|
||||||
|
|
||||||
Surface new_surface = CreateSurface(new_params);
|
Surface new_surface = CreateSurface(new_params);
|
||||||
if (load_if_create)
|
if (load_if_create)
|
||||||
@ -802,8 +783,8 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Pica::TexturingRegs::Full
|
|||||||
return GetSurface(params, ScaleMatch::Ignore, true);
|
return GetSurface(params, ScaleMatch::Ignore, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr float GetResolutionScaleFactor() {
|
constexpr u16 GetResolutionScaleFactor() {
|
||||||
return Settings::values.resolution_factor == 0.0f ?
|
return !Settings::values.resolution_factor ?
|
||||||
VideoCore::g_emu_window->GetFramebufferLayout().GetScalingRatio() :
|
VideoCore::g_emu_window->GetFramebufferLayout().GetScalingRatio() :
|
||||||
Settings::values.resolution_factor;
|
Settings::values.resolution_factor;
|
||||||
}
|
}
|
||||||
@ -834,7 +815,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool usin
|
|||||||
color_params.is_tiled = depth_params.is_tiled = true;
|
color_params.is_tiled = depth_params.is_tiled = true;
|
||||||
|
|
||||||
// update resolution_scale_factor and reset cache if changed
|
// update resolution_scale_factor and reset cache if changed
|
||||||
static float resolution_scale_factor = GetResolutionScaleFactor();
|
static u16 resolution_scale_factor = GetResolutionScaleFactor();
|
||||||
if (resolution_scale_factor != GetResolutionScaleFactor()) {
|
if (resolution_scale_factor != GetResolutionScaleFactor()) {
|
||||||
resolution_scale_factor = GetResolutionScaleFactor();
|
resolution_scale_factor = GetResolutionScaleFactor();
|
||||||
FlushAll();
|
FlushAll();
|
||||||
@ -845,19 +826,17 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool usin
|
|||||||
color_params.width = depth_params.width = config.GetWidth();
|
color_params.width = depth_params.width = config.GetWidth();
|
||||||
color_params.height = depth_params.height = config.GetHeight();
|
color_params.height = depth_params.height = config.GetHeight();
|
||||||
color_params.pixel_format = SurfaceParams::PixelFormatFromColorFormat(config.color_format);
|
color_params.pixel_format = SurfaceParams::PixelFormatFromColorFormat(config.color_format);
|
||||||
color_params.res_scale_height = resolution_scale_factor;
|
color_params.res_scale = resolution_scale_factor;
|
||||||
color_params.res_scale_width = resolution_scale_factor;
|
|
||||||
color_params.UpdateParams();
|
color_params.UpdateParams();
|
||||||
|
|
||||||
MathUtil::Rectangle<int> rect{};
|
MathUtil::Rectangle<u32> rect{};
|
||||||
Surface color_surface = nullptr;
|
Surface color_surface = nullptr;
|
||||||
if (using_color_fb)
|
if (using_color_fb)
|
||||||
std::tie(color_surface, rect) = GetSurfaceSubRect(color_params, ScaleMatch::Exact, true);
|
std::tie(color_surface, rect) = GetSurfaceSubRect(color_params, ScaleMatch::Exact, true);
|
||||||
|
|
||||||
depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(config.depth_format);
|
depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(config.depth_format);
|
||||||
depth_params.addr = config.GetDepthBufferPhysicalAddress();
|
depth_params.addr = config.GetDepthBufferPhysicalAddress();
|
||||||
depth_params.res_scale_height = resolution_scale_factor;
|
depth_params.res_scale = resolution_scale_factor;
|
||||||
depth_params.res_scale_width = resolution_scale_factor;
|
|
||||||
depth_params.UpdateParams();
|
depth_params.UpdateParams();
|
||||||
|
|
||||||
Surface depth_surface = nullptr;
|
Surface depth_surface = nullptr;
|
||||||
@ -900,9 +879,9 @@ Surface RasterizerCacheOpenGL::GetFillSurface(const GPU::Regs::MemoryFillConfig&
|
|||||||
}
|
}
|
||||||
|
|
||||||
SurfaceRect_Tuple RasterizerCacheOpenGL::GetTexCopySurface(const SurfaceParams& params) {
|
SurfaceRect_Tuple RasterizerCacheOpenGL::GetTexCopySurface(const SurfaceParams& params) {
|
||||||
MathUtil::Rectangle<int> rect{};
|
MathUtil::Rectangle<u32> rect{};
|
||||||
|
|
||||||
Surface match_surface = FindMatch<MatchType::TexCopy | MatchType::Invalid>(surface_cache, params, ScaleMatch::Ignore);
|
Surface match_surface = FindMatch<MatchFlags::TexCopy | MatchFlags::Invalid>(surface_cache, params, ScaleMatch::Ignore);
|
||||||
|
|
||||||
if (match_surface != nullptr) {
|
if (match_surface != nullptr) {
|
||||||
ValidateSurface(match_surface, params.addr, params.size);
|
ValidateSurface(match_surface, params.addr, params.size);
|
||||||
@ -964,7 +943,7 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, PAddr addr,
|
|||||||
}
|
}
|
||||||
params.UpdateParams();
|
params.UpdateParams();
|
||||||
|
|
||||||
Surface match_surface = FindMatch<MatchType::SubRect | MatchType::Copy>(surface_cache, params, ScaleMatch::Ignore);
|
Surface match_surface = FindMatch<MatchFlags::SubRect | MatchFlags::Copy>(surface_cache, params, ScaleMatch::Ignore);
|
||||||
|
|
||||||
if (match_surface != nullptr) {
|
if (match_surface != nullptr) {
|
||||||
if (!match_surface->CanSubRect(params)) {
|
if (!match_surface->CanSubRect(params)) {
|
||||||
@ -1046,8 +1025,6 @@ void RasterizerCacheOpenGL::InvalidateRegion(PAddr addr, u32 size, const Surface
|
|||||||
region_owner->invalid_regions.erase(invalid_interval);
|
region_owner->invalid_regions.erase(invalid_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceSet remove_surfaces;
|
|
||||||
|
|
||||||
for (auto& pair : RangeFromInterval(surface_cache, invalid_interval)) {
|
for (auto& pair : RangeFromInterval(surface_cache, invalid_interval)) {
|
||||||
for (auto& cached_surface : pair.second) {
|
for (auto& cached_surface : pair.second) {
|
||||||
if (cached_surface == region_owner)
|
if (cached_surface == region_owner)
|
||||||
@ -1085,6 +1062,7 @@ void RasterizerCacheOpenGL::InvalidateRegion(PAddr addr, u32 size, const Surface
|
|||||||
|
|
||||||
for (auto& remove_surface : remove_surfaces)
|
for (auto& remove_surface : remove_surfaces)
|
||||||
UnregisterSurface(remove_surface);
|
UnregisterSurface(remove_surface);
|
||||||
|
remove_surfaces.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Surface RasterizerCacheOpenGL::CreateSurface(const SurfaceParams& params) {
|
Surface RasterizerCacheOpenGL::CreateSurface(const SurfaceParams& params) {
|
||||||
|
@ -39,8 +39,8 @@ using SurfaceInterval = SurfaceCache::interval_type;
|
|||||||
static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() &&
|
static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() &&
|
||||||
std::is_same<SurfaceMap::interval_type, SurfaceCache::interval_type>(), "incorrect interval types");
|
std::is_same<SurfaceMap::interval_type, SurfaceCache::interval_type>(), "incorrect interval types");
|
||||||
|
|
||||||
using SurfaceRect_Tuple = std::tuple<Surface, MathUtil::Rectangle<int>>;
|
using SurfaceRect_Tuple = std::tuple<Surface, MathUtil::Rectangle<u32>>;
|
||||||
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<int>>;
|
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>;
|
||||||
|
|
||||||
using PageMap = boost::icl::interval_map<u32, int>;
|
using PageMap = boost::icl::interval_map<u32, int>;
|
||||||
|
|
||||||
@ -51,8 +51,6 @@ enum class ScaleMatch {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SurfaceParams {
|
struct SurfaceParams {
|
||||||
explicit SurfaceParams();
|
|
||||||
|
|
||||||
enum class PixelFormat {
|
enum class PixelFormat {
|
||||||
// First 5 formats are shared between textures and color buffers
|
// First 5 formats are shared between textures and color buffers
|
||||||
RGBA8 = 0,
|
RGBA8 = 0,
|
||||||
@ -200,19 +198,19 @@ struct SurfaceParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 GetScaledWidth() const {
|
u32 GetScaledWidth() const {
|
||||||
return static_cast<u32>(width * res_scale_width);
|
return width * res_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetScaledHeight() const {
|
u32 GetScaledHeight() const {
|
||||||
return static_cast<u32>(height * res_scale_height);
|
return height * res_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
MathUtil::Rectangle<int> GetRect() const {
|
MathUtil::Rectangle<u32> GetRect() const {
|
||||||
return MathUtil::Rectangle<int>(0, 0, width, height);
|
return { 0, 0, width, height };
|
||||||
}
|
}
|
||||||
|
|
||||||
MathUtil::Rectangle<int> GetScaledRect() const {
|
MathUtil::Rectangle<u32> GetScaledRect() const {
|
||||||
return MathUtil::Rectangle<int>(0, 0, GetScaledWidth(), GetScaledHeight());
|
return { 0, 0, GetScaledWidth(), GetScaledHeight() };
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PixelsInBytes(u32 size) const {
|
u32 PixelsInBytes(u32 size) const {
|
||||||
@ -226,8 +224,7 @@ struct SurfaceParams {
|
|||||||
u32 width = 0;
|
u32 width = 0;
|
||||||
u32 height = 0;
|
u32 height = 0;
|
||||||
u32 stride = 0;
|
u32 stride = 0;
|
||||||
float res_scale_width = 1.f;
|
u16 res_scale = 1;
|
||||||
float res_scale_height = 1.f;
|
|
||||||
|
|
||||||
bool is_tiled = false;
|
bool is_tiled = false;
|
||||||
u32 bytes_per_pixel = 0;
|
u32 bytes_per_pixel = 0;
|
||||||
@ -239,11 +236,10 @@ struct CachedSurface : SurfaceParams {
|
|||||||
bool ExactMatch(const SurfaceParams& other_surface) const;
|
bool ExactMatch(const SurfaceParams& other_surface) const;
|
||||||
bool CanSubRect(const SurfaceParams& sub_surface) const;
|
bool CanSubRect(const SurfaceParams& sub_surface) const;
|
||||||
bool CanCopy(const SurfaceParams& dest_surface) const;
|
bool CanCopy(const SurfaceParams& dest_surface) const;
|
||||||
//bool CanPartialCopy(const SurfaceParams& dest_surface) const;
|
|
||||||
bool CanTexCopy(const SurfaceParams& texcopy_params) const;
|
bool CanTexCopy(const SurfaceParams& texcopy_params) const;
|
||||||
|
|
||||||
MathUtil::Rectangle<int> GetSubRect(const SurfaceParams& sub_surface) const;
|
MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const;
|
||||||
MathUtil::Rectangle<int> GetScaledSubRect(const SurfaceParams& sub_surface) const;
|
MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const;
|
||||||
|
|
||||||
bool IsRegionValid(const SurfaceInterval& interval) const {
|
bool IsRegionValid(const SurfaceInterval& interval) const {
|
||||||
return (invalid_regions.find(interval) == invalid_regions.end());
|
return (invalid_regions.find(interval) == invalid_regions.end());
|
||||||
@ -283,8 +279,8 @@ public:
|
|||||||
~RasterizerCacheOpenGL();
|
~RasterizerCacheOpenGL();
|
||||||
|
|
||||||
/// Blit one surface's texture to another
|
/// Blit one surface's texture to another
|
||||||
bool BlitSurfaces(const Surface& src_surface, const MathUtil::Rectangle<int>& src_rect,
|
bool BlitSurfaces(const Surface& src_surface, const MathUtil::Rectangle<u32>& src_rect,
|
||||||
const Surface& dst_surface, const MathUtil::Rectangle<int>& dst_rect);
|
const Surface& dst_surface, const MathUtil::Rectangle<u32>& dst_rect);
|
||||||
|
|
||||||
/// Load a texture from 3DS memory to OpenGL and cache it (if not already cached)
|
/// Load a texture from 3DS memory to OpenGL and cache it (if not already cached)
|
||||||
Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale, bool load_if_create);
|
Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale, bool load_if_create);
|
||||||
@ -334,4 +330,5 @@ private:
|
|||||||
SurfaceCache surface_cache;
|
SurfaceCache surface_cache;
|
||||||
SurfaceMap dirty_regions;
|
SurfaceMap dirty_regions;
|
||||||
PageMap cached_pages;
|
PageMap cached_pages;
|
||||||
|
SurfaceSet remove_surfaces;
|
||||||
};
|
};
|
||||||
|
@ -41,7 +41,7 @@ struct LightSrc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
layout (std140) uniform shader_data {
|
layout (std140) uniform shader_data {
|
||||||
vec2 framebuffer_scale;
|
int framebuffer_scale;
|
||||||
int alphatest_ref;
|
int alphatest_ref;
|
||||||
float depth_scale;
|
float depth_scale;
|
||||||
float depth_offset;
|
float depth_offset;
|
||||||
|
Loading…
Reference in New Issue
Block a user