Final cleanups, reviews, etc.

This commit is contained in:
Fernando Sahmkow 2017-01-18 15:59:38 -05:00
parent 5382a76de1
commit f528c8bdaa
11 changed files with 97 additions and 188 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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<u8[]> decoded_texture = codec->transferInternalBuffer();
@ -663,7 +663,7 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
std::vector<u8> 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())

View File

@ -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<u8[]> 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<u8*>(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<u8*>(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);
}

View File

@ -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<u8> 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<u8[]> 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<u8[]> 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 {

View File

@ -22,6 +22,3 @@
// Encoders
#include "encoders.cpp"
// Lookup Texture
#include "lookup.cpp"

View File

@ -16,7 +16,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -35,7 +34,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -54,7 +52,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -73,7 +70,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -92,7 +88,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -111,7 +106,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -130,7 +124,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -149,7 +142,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -168,7 +160,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -187,7 +178,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -206,7 +196,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -225,7 +214,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -244,7 +232,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -263,7 +250,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -282,7 +268,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -301,7 +286,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {
@ -320,7 +304,6 @@ public:
}
void decode();
void encode();
const Math::Vec4<u8> lookupTexel(u32 x, u32 y);
protected:
virtual void setSize() {

View File

@ -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 codec(u8*, u8*, size_t), size_t nibbles, size_t lines_per_block>
void tiling_pass(u8* linear, u8* tiled, u32 x_blocks) {
template <size_t nibbles, size_t lines_per_block>
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;

View File

@ -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);

View File

@ -1,110 +0,0 @@
const Math::Vec4<u8> RGBACodec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRGBA8(tmp);
}
const Math::Vec4<u8> RGBCodec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRGB8(tmp);
}
const Math::Vec4<u8> RGB5A1Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRGB5A1(tmp);
}
const Math::Vec4<u8> RGB565Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRGB565(tmp);
}
const Math::Vec4<u8> RGBA4Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRGBA4(tmp);
}
const Math::Vec4<u8> RG8Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRG8(tmp);
}
const Math::Vec4<u8> IA8Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8 intensity = (texel & 0x00FF00) >> 8;
u8 alpha = (texel & 0x0000FF);
Math::Vec4<u8> result(intensity, intensity, intensity, alpha);
return result;
}
const Math::Vec4<u8> 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<u8> result(intensity, intensity, intensity, alpha);
return result;
}
const Math::Vec4<u8> I8Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8 intensity = (texel & 0x0000FF);
Math::Vec4<u8> result(intensity, intensity, intensity, 255);
return result;
}
const Math::Vec4<u8> 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<u8> result(intensity, intensity, intensity, 255);
return result;
}
const Math::Vec4<u8> A8Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8 alpha = (texel & 0x0000FF);
Math::Vec4<u8> result(0, 0, 0, alpha);
return result;
}
const Math::Vec4<u8> 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<u8> result(0, 0, 0, alpha);
return result;
}
const Math::Vec4<u8> ETC1Codec::lookupTexel(u32 x, u32 y) {
Math::Vec4<u8> result(0, 0, 0, 255);
return result;
}
const Math::Vec4<u8> ETC1A4Codec::lookupTexel(u32 x, u32 y) {
Math::Vec4<u8> result(0, 0, 0, 255);
return result;
}
const Math::Vec4<u8> D16Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRG8(tmp);
}
const Math::Vec4<u8> D24Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRGB8(tmp);
}
const Math::Vec4<u8> D24S8Codec::lookupTexel(u32 x, u32 y) {
u32 texel = super::getTexel(x, y);
u8* tmp = reinterpret_cast<u8*>(&texel);
return Color::DecodeRGBA8(tmp);
}

View File

@ -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 <void codec(u8*, u8*, size_t), size_t nibbles, u32 blocks, size_t block_size>
__forceinline static void swizzle_block(u8*& morton_block, u8* linear_block);
inline static void swizzle_block(u8*& morton_block, u8* linear_block);
template <void codec(u8*, u8*, size_t), size_t nibbles, u32 block_index, u32 blocks,
size_t block_size>
__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 <void codec(u8*, u8*, size_t), size_t nibbles, u32 blocks, size_t block_size>
__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