diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index b476c2571..350bbc75a 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -332,12 +332,14 @@ static void FlushIOFile(png_structp png_ptr) { } #endif +#ifdef HAVE_PNG void clean_mess(png_infop info_ptr, png_structp png_ptr) { if (info_ptr != nullptr) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); if (png_ptr != nullptr) png_destroy_write_struct(&png_ptr, (png_infopp) nullptr); } +#endif void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { #ifndef HAVE_PNG diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index e8ceee163..d5aa81915 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -978,10 +978,12 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader &old_stencil](Pica::Regs::StencilAction action) { u8 new_stencil = PerformStencilAction(action, old_stencil, stencil_test.reference_value); + // clang-format off if (g_state.regs.framebuffer.allow_depth_stencil_write != 0) SetStencil(x >> 4, y >> 4, (new_stencil & stencil_test.write_mask) | (old_stencil & ~stencil_test.write_mask)); + // clang-format on }; if (stencil_action_enable) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index d831e3e91..69caa6915 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -26,7 +26,7 @@ #include "video_core/video_core.h" #define TEXTURE_CACHE_SIZE (1024 * 1024 * 8) // 8MB inner cache for decoding/encoding -alignas(64) static u8 TextureCache[TEXTURE_CACHE_SIZE]; +alignas(64) static u8 texture_cache[TEXTURE_CACHE_SIZE]; struct FormatTuple { GLint internal_format; @@ -314,12 +314,12 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo codec->validate(); if (!codec->invalid()) { u32 estimated_size = - params.width * params.height * codec->getInternalBytesPerPixel(); + (params.width * params.height * codec->getInternalBitsPerPixel()) / 8; if (estimated_size <= TEXTURE_CACHE_SIZE) { - codec->setExternalBuffer(TextureCache); + codec->setExternalBuffer(texture_cache); codec->decode(); glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, - params.height, 0, tuple.format, tuple.type, TextureCache); + params.height, 0, tuple.format, tuple.type, texture_cache); } else { codec->decode(); std::unique_ptr decoded_texture = codec->transferInternalBuffer(); @@ -663,7 +663,7 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { std::vector temp_gl_buffer; u8* temporal_buffer; if (size <= TEXTURE_CACHE_SIZE) - temporal_buffer = TextureCache; + temporal_buffer = texture_cache; else { temp_gl_buffer.resize(size); temporal_buffer = temp_gl_buffer.data(); @@ -678,7 +678,7 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { codec->configTiling(true, 8); // change 8 for 32 in case the mage is tiled // on blocks of 32x32 codec->configRGBATransform(!native_format[(u32)surface->pixel_format]); - codec->configPreConvertedRGBA(!native_format[(u32)surface->pixel_format]); + codec->configPreconvertedRGBA(!native_format[(u32)surface->pixel_format]); codec->setExternalBuffer(dst_buffer); codec->validate(); if (!codec->invalid()) diff --git a/src/video_core/texture/codec.cpp b/src/video_core/texture/codec.cpp index e16d0589d..c4389605d 100644 --- a/src/video_core/texture/codec.cpp +++ b/src/video_core/texture/codec.cpp @@ -36,7 +36,7 @@ void Codec::configRGBATransform(bool active) { this->raw_RGBA = active; } -void Codec::configPreConvertedRGBA(bool active) { +void Codec::configPreconvertedRGBA(bool active) { this->preconverted = active; } @@ -53,7 +53,7 @@ std::unique_ptr Codec::transferInternalBuffer() { return nullptr; } -bool Codec::invalid() { +bool Codec::invalid() const { return this->invalid_state; } @@ -101,19 +101,19 @@ void Codec::validate() { this->invalid_state = false; } -inline void Codec::decode_morton_pass() { +inline void Codec::decode_morton_pass() const { if (this->morton_pass_tiling == 8) - Decoders::Morton_8x8(this->target_buffer, this->passing_buffer, this->width, this->height, - this->start_nibbles_size * 4); + Decoders::Morton_8x8(const_cast(this->target_buffer), this->passing_buffer, + this->width, this->height, this->start_nibbles_size * 4); } -inline void Codec::encode_morton_pass() { +inline void Codec::encode_morton_pass() const { if (this->morton_pass_tiling == 8) - Encoders::Morton_8x8(this->passing_buffer, this->target_buffer, this->width, this->height, - this->start_nibbles_size * 4); + Encoders::Morton_8x8(this->passing_buffer, const_cast(this->target_buffer), + this->width, this->height, this->start_nibbles_size * 4); } -u32 Codec::getTexel(u32 x, u32 y) { +u32 Codec::getTexel(const u32 x, const u32 y) const { const u32 tiling = this->morton_pass_tiling; const u8* position = this->getTile(x, y); const u32 bpp = this->start_nibbles_size * 4; // bits per pixel @@ -128,12 +128,12 @@ u32 Codec::getTexel(u32 x, u32 y) { return result; } -u8* Codec::getTile(u32 x, u32 y) { +const u8* Codec::getTile(const u32 x, const u32 y) const { const u32 tiling = this->morton_pass_tiling; - x = (x / tiling) * tiling; - y = (y / tiling) * tiling; + const u32 x2 = (x / tiling) * tiling; + const u32 y2 = (y / tiling) * tiling; const u32 bpp = this->start_nibbles_size * 4; - const u64 offset = ((x + y * this->width) * bpp) / 8; + const u64 offset = ((x2 + y2 * this->width) * bpp) / 8; return (this->target_buffer + offset); } diff --git a/src/video_core/texture/codec.h b/src/video_core/texture/codec.h index c985aaa1c..45e8f377c 100644 --- a/src/video_core/texture/codec.h +++ b/src/video_core/texture/codec.h @@ -14,43 +14,70 @@ namespace Texture { class Codec { public: - Codec(u8* target, u32 width, u32 height) { + Codec(const u8* target, u32 width, u32 height) { this->target_buffer = target; this->setWidth(width); this->setHeight(height); } virtual ~Codec() {} + /* + * Orders the codec to decode the 'target_buffer' with the current + * configurations. + */ virtual void decode(); + + /* + * Orders the codec to encode the 'target_buffer' with the current + * configurations. + */ virtual void encode(); - // for legacy code compatibility - // returns the corresponding texel in RGBA format. - // prefer full decode/encode than texel lookups for full image decoding. - virtual const Math::Vec4 lookupTexel(u32 x, u32 y) = 0; - - inline void setWidth(u32 width) { - this->width = width; - } - - inline void setHeight(u32 height) { - this->height = height; - } - - inline u32 getInternalBytesPerPixel() { - return this->expected_nibbles_size / 2; + /* + * returns the number of bits used by the internal buffer. + */ + inline u32 getInternalBitsPerPixel() const { + return this->expected_nibbles_size * 4; } // Common Passes + /* + * Configures the texture tiling. + * @param active : do the tiling/swizzling pass. + * @param tiling : texture tiling. + */ void configTiling(bool active, u32 tiling); - void configRGBATransform(bool active); - void configPreConvertedRGBA(bool active); + /* + * On Decode: + * Transforms the result into RGBA format. + * On Encode: + * Transforms the result into it's original format if the input buffer + * was previously converted to RGBA. + */ + void configRGBATransform(bool active); + + /* + * On Decode: + * Does nothing (nop). + * On Encode: + * Tells the codec that the input buffer was previously decoded. + */ + void configPreconvertedRGBA(bool active); + + // Allows the use of an external buffer provided by the user for + // writting the result. void setExternalBuffer(u8* external); + + // Obtain the result of decode/encode operations when no external buffer had + // been set. std::unique_ptr transferInternalBuffer(); + // Run validation passes to the current configuration. virtual void validate(); - bool invalid(); + + // Check if the codec is in an ivalid state. Do this before decoding/encoding. + bool invalid() const; protected: u32 width; @@ -70,7 +97,7 @@ protected: this->start_nibbles_size = 8; }; - u8* target_buffer; // Initial read buffer + const u8* target_buffer; // Initial read buffer u8* passing_buffer; // pointer aliasing: Used and modified by passes std::unique_ptr internal_buffer; // used if no external buffer is provided bool external_result_buffer = false; @@ -79,10 +106,18 @@ protected: typedef Codec super; - inline void decode_morton_pass(); - inline void encode_morton_pass(); - u32 getTexel(u32 x, u32 y); - u8* getTile(u32 x, u32 y); + inline void setWidth(u32 width) { + this->width = width; + } + + inline void setHeight(u32 height) { + this->height = height; + } + + inline void decode_morton_pass() const; + inline void encode_morton_pass() const; + u32 getTexel(const u32 x, const u32 y) const; + const u8* getTile(const u32 x, const u32 y) const; }; namespace CodecFactory { diff --git a/src/video_core/texture/internal/codecs.cpp b/src/video_core/texture/internal/codecs.cpp index fdd8e1070..8b2eb3598 100644 --- a/src/video_core/texture/internal/codecs.cpp +++ b/src/video_core/texture/internal/codecs.cpp @@ -22,6 +22,3 @@ // Encoders #include "encoders.cpp" - -// Lookup Texture -#include "lookup.cpp" diff --git a/src/video_core/texture/internal/codecs.h b/src/video_core/texture/internal/codecs.h index c6b570d22..2a379ce26 100644 --- a/src/video_core/texture/internal/codecs.h +++ b/src/video_core/texture/internal/codecs.h @@ -16,7 +16,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -35,7 +34,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -54,7 +52,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -73,7 +70,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -92,7 +88,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -111,7 +106,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -130,7 +124,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -149,7 +142,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -168,7 +160,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -187,7 +178,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -206,7 +196,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -225,7 +214,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -244,7 +232,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -263,7 +250,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -282,7 +268,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -301,7 +286,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { @@ -320,7 +304,6 @@ public: } void decode(); void encode(); - const Math::Vec4 lookupTexel(u32 x, u32 y); protected: virtual void setSize() { diff --git a/src/video_core/texture/internal/etc1.cpp b/src/video_core/texture/internal/etc1.cpp index 9003c91a8..1af3c0c4b 100644 --- a/src/video_core/texture/internal/etc1.cpp +++ b/src/video_core/texture/internal/etc1.cpp @@ -126,19 +126,19 @@ inline void decode(u8* morton_pointer, u8* matrix_pointer, size_t read_size) { std::memcpy(matrix_pointer, morton_pointer, read_size); } -template -void tiling_pass(u8* linear, u8* tiled, u32 x_blocks) { +template +void tiling_pass(u8* linear, const u8* tiled, u32 x_blocks) { const size_t tiled_line_size = (lines_per_block * nibbles) / 2; const size_t row_length = x_blocks * tiled_line_size; for (u32 i = 0; i < lines_per_block; i++) { const u32 k = (lines_per_block - 1 - i); const size_t tiled_index = i * tiled_line_size; const size_t linear_index = k * row_length; - codec(tiled + tiled_index, linear + linear_index, tiled_line_size); + std::memcpy(linear + linear_index, tiled + tiled_index, tiled_line_size); } } -inline void etc1_pass(u8* etc1_buffer, u8* linear_buffer, u32 x_blocks) { +inline void etc1_pass(const u8* etc1_buffer, u8* linear_buffer, u32 x_blocks) { const size_t line = 8 * 4; alignas(64) u8 tmp[line * 8]; for (u32 i = 0; i < 4; i++) { @@ -153,10 +153,10 @@ inline void etc1_pass(u8* etc1_buffer, u8* linear_buffer, u32 x_blocks) { } } } - tiling_pass<&decode, 8, 8>(linear_buffer, tmp, x_blocks); + tiling_pass<8, 8>(linear_buffer, tmp, x_blocks); } -inline void etc1a4_pass(u8* etc1_buffer, u8* linear_buffer, u32 x_blocks) { +inline void etc1a4_pass(const u8* etc1_buffer, u8* linear_buffer, u32 x_blocks) { const size_t line = 8 * 4; alignas(64) u8 tmp[line * 8]; for (u32 i = 0; i < 4; i++) { @@ -175,10 +175,10 @@ inline void etc1a4_pass(u8* etc1_buffer, u8* linear_buffer, u32 x_blocks) { } } } - tiling_pass<&decode, 8, 8>(linear_buffer, tmp, x_blocks); + tiling_pass<8, 8>(linear_buffer, tmp, x_blocks); } -void ETC1A4(u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height) { +void ETC1A4(const u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height) { const u32 x_blocks = (width / 8); const u32 y_blocks = (height / 8); const size_t line_size = 8 * 4; @@ -196,7 +196,7 @@ void ETC1A4(u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height) { } } -void ETC1(u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height) { +void ETC1(const u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height) { const u32 x_blocks = (width / 8); const u32 y_blocks = (height / 8); const size_t line_size = 8 * 4; diff --git a/src/video_core/texture/internal/etc1.h b/src/video_core/texture/internal/etc1.h index 492f19729..ed68b8b92 100644 --- a/src/video_core/texture/internal/etc1.h +++ b/src/video_core/texture/internal/etc1.h @@ -2,5 +2,5 @@ #include "common/common_types.h" -void ETC1(u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height); -void ETC1A4(u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height); +void ETC1(const u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height); +void ETC1A4(const u8* etc1_buffer, u8* matrix_buffer, u32 width, u32 height); diff --git a/src/video_core/texture/internal/lookup.cpp b/src/video_core/texture/internal/lookup.cpp deleted file mode 100644 index 369fe326f..000000000 --- a/src/video_core/texture/internal/lookup.cpp +++ /dev/null @@ -1,110 +0,0 @@ - -const Math::Vec4 RGBACodec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRGBA8(tmp); -} - -const Math::Vec4 RGBCodec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRGB8(tmp); -} - -const Math::Vec4 RGB5A1Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRGB5A1(tmp); -} - -const Math::Vec4 RGB565Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRGB565(tmp); -} - -const Math::Vec4 RGBA4Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRGBA4(tmp); -} - -const Math::Vec4 RG8Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRG8(tmp); -} - -const Math::Vec4 IA8Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8 intensity = (texel & 0x00FF00) >> 8; - u8 alpha = (texel & 0x0000FF); - Math::Vec4 result(intensity, intensity, intensity, alpha); - return result; -} - -const Math::Vec4 IA4Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8 intensity = Color::Convert4To8((texel & 0x00F0) >> 4); - u8 alpha = Color::Convert4To8(texel & 0x0F); - Math::Vec4 result(intensity, intensity, intensity, alpha); - return result; -} - -const Math::Vec4 I8Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8 intensity = (texel & 0x0000FF); - Math::Vec4 result(intensity, intensity, intensity, 255); - return result; -} - -const Math::Vec4 I4Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - const u32 bit = 1 - (x % 2); - u8 intensity = Color::Convert4To8((texel & 0x0000FF) >> bit); - Math::Vec4 result(intensity, intensity, intensity, 255); - return result; -} - -const Math::Vec4 A8Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8 alpha = (texel & 0x0000FF); - Math::Vec4 result(0, 0, 0, alpha); - return result; -} - -const Math::Vec4 A4Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - const u32 bit = 1 - (x % 2); - u8 alpha = Color::Convert4To8((texel & 0x0000FF) >> bit); - Math::Vec4 result(0, 0, 0, alpha); - return result; -} - -const Math::Vec4 ETC1Codec::lookupTexel(u32 x, u32 y) { - Math::Vec4 result(0, 0, 0, 255); - return result; -} - -const Math::Vec4 ETC1A4Codec::lookupTexel(u32 x, u32 y) { - Math::Vec4 result(0, 0, 0, 255); - return result; -} - -const Math::Vec4 D16Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRG8(tmp); -} - -const Math::Vec4 D24Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRGB8(tmp); -} - -const Math::Vec4 D24S8Codec::lookupTexel(u32 x, u32 y) { - u32 texel = super::getTexel(x, y); - u8* tmp = reinterpret_cast(&texel); - return Color::DecodeRGBA8(tmp); -} diff --git a/src/video_core/texture/internal/morton8x8_optimized.cpp b/src/video_core/texture/internal/morton8x8_optimized.cpp index d8511be56..95c64dfc9 100644 --- a/src/video_core/texture/internal/morton8x8_optimized.cpp +++ b/src/video_core/texture/internal/morton8x8_optimized.cpp @@ -30,7 +30,7 @@ #define __no_inline __attribute__((noinline)) #define __hot __attribute__((hot)) #if !defined(__forceinline) -#define __forceinline attribute__((always_inline)) +#define __forceinline __attribute__((always_inline)) #endif #else #define __hot @@ -72,11 +72,11 @@ constexpr u32 isBottom(u32 block_index) { } template -__forceinline static void swizzle_block(u8*& morton_block, u8* linear_block); +inline static void swizzle_block(u8*& morton_block, u8* linear_block); template -__forceinline static void swizzle_block_aux(u8*& morton_block, u8* linear_block) { +inline static void swizzle_block_aux(u8*& morton_block, u8* linear_block) { // move the linear_block pointer to the appropiate block const size_t right = isRight(block_index) * (blocks * nibbles) / 2; const size_t down = isBottom(block_index) * block_size; @@ -85,7 +85,7 @@ __forceinline static void swizzle_block_aux(u8*& morton_block, u8* linear_block) } template -__forceinline static void swizzle_block(u8*& morton_block, u8* linear_block) { +inline static void swizzle_block(u8*& morton_block, u8* linear_block) { const size_t new_block_size = block_size / 2; if (blocks <= 2) { // We handle 2*2 blocks on z-order