diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 2975a7a6c..6a1641c81 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -27,6 +27,9 @@ add_library(video_core STATIC rasterizer_cache/pixel_format.h rasterizer_cache/rasterizer_cache.cpp rasterizer_cache/rasterizer_cache.h + rasterizer_cache/rasterizer_cache_types.h + rasterizer_cache/rasterizer_cache_utils.cpp + rasterizer_cache/rasterizer_cache_utils.h rasterizer_cache/surface_params.cpp rasterizer_cache/surface_params.h renderer_opengl/frame_dumper_opengl.cpp diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.cpp b/src/video_core/rasterizer_cache/rasterizer_cache.cpp index 11c0eb69f..0be54679e 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.cpp +++ b/src/video_core/rasterizer_cache/rasterizer_cache.cpp @@ -38,50 +38,6 @@ namespace OpenGL { -constexpr FormatTuple tex_tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}; - -static constexpr std::array depth_format_tuples = {{ - {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16 - {}, - {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24 - {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8 -}}; - -static constexpr std::array fb_format_tuples = {{ - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // RGBA8 - {GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE}, // RGB8 - {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1 - {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565 - {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4 -}}; - -// Same as above, with minor changes for OpenGL ES. Replaced -// GL_UNSIGNED_INT_8_8_8_8 with GL_UNSIGNED_BYTE and -// GL_BGR with GL_RGB -static constexpr std::array fb_format_tuples_oes = {{ - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA8 - {GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE}, // RGB8 - {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1 - {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565 - {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4 -}}; - -const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { - const SurfaceType type = GetFormatType(pixel_format); - const std::size_t format_index = static_cast(pixel_format); - - if (type == SurfaceType::Color) { - ASSERT(format_index < fb_format_tuples.size()); - return (GLES ? fb_format_tuples_oes : fb_format_tuples)[format_index]; - } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { - const std::size_t tuple_idx = format_index - 14; - ASSERT(tuple_idx < depth_format_tuples.size()); - return depth_format_tuples[tuple_idx]; - } - - return tex_tuple; -} - template static constexpr auto RangeFromInterval(Map& map, const Interval& interval) { return boost::make_iterator_range(map.equal_range(interval)); diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index b6932dea7..d5f20ce92 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -27,109 +27,13 @@ #include "common/common_types.h" #include "common/math_util.h" #include "core/custom_tex_cache.h" -#include "video_core/renderer_opengl/gl_resource_manager.h" +#include "video_core/rasterizer_cache/rasterizer_cache_utils.h" #include "video_core/rasterizer_cache/surface_params.h" +#include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/texture/texture_decode.h" namespace OpenGL { -class RasterizerCacheOpenGL; -class TextureFilterer; -class FormatReinterpreterOpenGL; - -struct FormatTuple { - GLint internal_format; - GLenum format; - GLenum type; -}; - -const FormatTuple& GetFormatTuple(PixelFormat pixel_format); - -struct HostTextureTag { - FormatTuple format_tuple; - u32 width; - u32 height; - - bool operator==(const HostTextureTag& rhs) const noexcept { - return std::tie(format_tuple.format, format_tuple.internal_format, width, height) == - std::tie(rhs.format_tuple.format, rhs.format_tuple.internal_format, rhs.width, - rhs.height); - }; -}; - -struct TextureCubeConfig { - PAddr px; - PAddr nx; - PAddr py; - PAddr ny; - PAddr pz; - PAddr nz; - u32 width; - Pica::TexturingRegs::TextureFormat format; - - bool operator==(const TextureCubeConfig& rhs) const { - return std::tie(px, nx, py, ny, pz, nz, width, format) == - std::tie(rhs.px, rhs.nx, rhs.py, rhs.ny, rhs.pz, rhs.nz, rhs.width, rhs.format); - } - - bool operator!=(const TextureCubeConfig& rhs) const { - return !(*this == rhs); - } -}; - -} // namespace OpenGL - -namespace std { -template <> -struct hash { - std::size_t operator()(const OpenGL::HostTextureTag& tag) const noexcept { - std::size_t hash = 0; - boost::hash_combine(hash, tag.format_tuple.format); - boost::hash_combine(hash, tag.format_tuple.internal_format); - boost::hash_combine(hash, tag.width); - boost::hash_combine(hash, tag.height); - return hash; - } -}; - -template <> -struct hash { - std::size_t operator()(const OpenGL::TextureCubeConfig& config) const noexcept { - std::size_t hash = 0; - boost::hash_combine(hash, config.px); - boost::hash_combine(hash, config.nx); - boost::hash_combine(hash, config.py); - boost::hash_combine(hash, config.ny); - boost::hash_combine(hash, config.pz); - boost::hash_combine(hash, config.nz); - boost::hash_combine(hash, config.width); - boost::hash_combine(hash, static_cast(config.format)); - return hash; - } -}; -} // namespace std - -namespace OpenGL { - -using SurfaceSet = std::set; - -using SurfaceRegions = boost::icl::interval_set; -using SurfaceMap = - boost::icl::interval_map; -using SurfaceCache = - boost::icl::interval_map; - -static_assert(std::is_same() && - std::is_same(), - "incorrect interval types"); - -using SurfaceRect_Tuple = std::tuple>; -using SurfaceSurfaceRect_Tuple = std::tuple>; - -using PageMap = boost::icl::interval_map; - enum class ScaleMatch { Exact, // only accept same res scale Upscale, // only allow higher scale than params @@ -260,6 +164,8 @@ struct CachedTextureCube { }; class TextureDownloaderES; +class TextureFilterer; +class FormatReinterpreterOpenGL; class RasterizerCacheOpenGL : NonCopyable { public: diff --git a/src/video_core/rasterizer_cache/rasterizer_cache_types.h b/src/video_core/rasterizer_cache/rasterizer_cache_types.h new file mode 100644 index 000000000..1074a50ac --- /dev/null +++ b/src/video_core/rasterizer_cache/rasterizer_cache_types.h @@ -0,0 +1,38 @@ +// Copyright 2022 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once +#include +#include +#include +#include +#include "common/common_types.h" +#include "common/math_util.h" + +namespace OpenGL { + +class CachedSurface; +using Surface = std::shared_ptr; + +// Declare rasterizer interval types +using SurfaceInterval = boost::icl::right_open_interval; +using SurfaceSet = std::set; +using SurfaceRegions = boost::icl::interval_set; +using SurfaceMap = boost::icl::interval_map; +using SurfaceCache = boost::icl::interval_map; + +static_assert(std::is_same() && + std::is_same(), + "Incorrect interval types"); + +using SurfaceRect_Tuple = std::tuple>; +using SurfaceSurfaceRect_Tuple = std::tuple>; +using PageMap = boost::icl::interval_map; + + +} // namespace OpenGL diff --git a/src/video_core/rasterizer_cache/rasterizer_cache_utils.cpp b/src/video_core/rasterizer_cache/rasterizer_cache_utils.cpp new file mode 100644 index 000000000..051aaa2d4 --- /dev/null +++ b/src/video_core/rasterizer_cache/rasterizer_cache_utils.cpp @@ -0,0 +1,56 @@ +// Copyright 2022 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once +#include +#include "video_core/rasterizer_cache/rasterizer_cache_utils.h" +#include "video_core/renderer_opengl/gl_vars.h" + +namespace OpenGL { + +constexpr FormatTuple tex_tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}; + +static constexpr std::array depth_format_tuples = {{ + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16 + {}, + {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24 + {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8 +}}; + +static constexpr std::array fb_format_tuples = {{ + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // RGBA8 + {GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE}, // RGB8 + {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1 + {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565 + {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4 +}}; + +// Same as above, with minor changes for OpenGL ES. Replaced +// GL_UNSIGNED_INT_8_8_8_8 with GL_UNSIGNED_BYTE and +// GL_BGR with GL_RGB +static constexpr std::array fb_format_tuples_oes = {{ + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA8 + {GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE}, // RGB8 + {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1 + {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565 + {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4 +}}; + +const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { + const SurfaceType type = GetFormatType(pixel_format); + const std::size_t format_index = static_cast(pixel_format); + + if (type == SurfaceType::Color) { + ASSERT(format_index < fb_format_tuples.size()); + return (GLES ? fb_format_tuples_oes : fb_format_tuples)[format_index]; + } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { + const std::size_t tuple_idx = format_index - 14; + ASSERT(tuple_idx < depth_format_tuples.size()); + return depth_format_tuples[tuple_idx]; + } + + return tex_tuple; +} + +} // namespace OpenGL diff --git a/src/video_core/rasterizer_cache/rasterizer_cache_utils.h b/src/video_core/rasterizer_cache/rasterizer_cache_utils.h new file mode 100644 index 000000000..928bd4041 --- /dev/null +++ b/src/video_core/rasterizer_cache/rasterizer_cache_utils.h @@ -0,0 +1,76 @@ +// Copyright 2022 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once +#include +#include +#include +#include +#include "common/hash.h" +#include "video_core/rasterizer_cache/pixel_format.h" + +namespace OpenGL { + +struct FormatTuple { + int internal_format; + u32 format; + u32 type; +}; + +const FormatTuple& GetFormatTuple(PixelFormat pixel_format); + +struct HostTextureTag { + FormatTuple format_tuple{}; + u32 width = 0; + u32 height = 0; + + bool operator==(const HostTextureTag& rhs) const noexcept { + return std::memcmp(this, &rhs, sizeof(HostTextureTag)) == 0; + }; + + const u64 Hash() const { + return Common::ComputeHash64(this, sizeof(HostTextureTag)); + } +}; + +struct TextureCubeConfig { + PAddr px; + PAddr nx; + PAddr py; + PAddr ny; + PAddr pz; + PAddr nz; + u32 width; + Pica::TexturingRegs::TextureFormat format; + + bool operator==(const TextureCubeConfig& rhs) const { + return std::memcmp(this, &rhs, sizeof(TextureCubeConfig)) == 0; + } + + bool operator!=(const TextureCubeConfig& rhs) const { + return std::memcmp(this, &rhs, sizeof(TextureCubeConfig)) != 0; + } + + const u64 Hash() const { + return Common::ComputeHash64(this, sizeof(TextureCubeConfig)); + } +}; + +} // namespace OpenGL + +namespace std { +template <> +struct hash { + std::size_t operator()(const OpenGL::HostTextureTag& tag) const noexcept { + return tag.Hash(); + } +}; + +template <> +struct hash { + std::size_t operator()(const OpenGL::TextureCubeConfig& config) const noexcept { + return config.Hash(); + } +}; +} // namespace std diff --git a/src/video_core/rasterizer_cache/surface_params.h b/src/video_core/rasterizer_cache/surface_params.h index 62f501ae1..0d26ad9a5 100644 --- a/src/video_core/rasterizer_cache/surface_params.h +++ b/src/video_core/rasterizer_cache/surface_params.h @@ -6,17 +6,11 @@ #include #include -#include -#include "common/math_util.h" #include "video_core/rasterizer_cache/pixel_format.h" +#include "video_core/rasterizer_cache/rasterizer_cache_types.h" namespace OpenGL { -struct CachedSurface; -using Surface = std::shared_ptr; - -using SurfaceInterval = boost::icl::right_open_interval; - class SurfaceParams { public: // Surface match traits diff --git a/src/video_core/renderer_opengl/texture_downloader_es.cpp b/src/video_core/renderer_opengl/texture_downloader_es.cpp index 54ea65cd4..4e96cfaa9 100644 --- a/src/video_core/renderer_opengl/texture_downloader_es.cpp +++ b/src/video_core/renderer_opengl/texture_downloader_es.cpp @@ -4,15 +4,11 @@ #include #include - #include - #include "common/logging/log.h" #include "video_core/rasterizer_cache/rasterizer_cache.h" #include "video_core/renderer_opengl/gl_state.h" -#include "video_core/renderer_opengl/gl_vars.h" #include "video_core/renderer_opengl/texture_downloader_es.h" - #include "shaders/depth_to_color.frag" #include "shaders/depth_to_color.vert" #include "shaders/ds_to_color.frag" @@ -78,13 +74,13 @@ void TextureDownloaderES::Test() { } }; LOG_INFO(Render_OpenGL, "GL_DEPTH24_STENCIL8 download test starting"); - test(depth_format_tuples[3], std::vector{}, 4096, + test(GetFormatTuple(PixelFormat::D24S8), std::vector{}, 4096, [](std::size_t idx) { return static_cast((idx << 8) | (idx & 0xFF)); }); LOG_INFO(Render_OpenGL, "GL_DEPTH_COMPONENT24 download test starting"); - test(depth_format_tuples[2], std::vector{}, 4096, + test(GetFormatTuple(PixelFormat::D24), std::vector{}, 4096, [](std::size_t idx) { return static_cast(idx << 8); }); LOG_INFO(Render_OpenGL, "GL_DEPTH_COMPONENT16 download test starting"); - test(depth_format_tuples[0], std::vector{}, 256, + test(GetFormatTuple(PixelFormat::D16), std::vector{}, 256, [](std::size_t idx) { return static_cast(idx); }); cur_state.Apply();